]> andersk Git - splint.git/commitdiff
Changes for the OS/2 port: cpplib.c (fixed cstring_replaceAll()
authorherbert <herbert>
Wed, 26 Sep 2001 10:42:37 +0000 (10:42 +0000)
committerherbert <herbert>
Wed, 26 Sep 2001 10:42:37 +0000 (10:42 +0000)
backslashes to slashes), cscanner.l (fixed includes for IBMC)
and constants.h (changed default rcfile name to .lclintrc).
Added files for building the OS/2 port: os2/ subdirectory
containing Makefile, batches and documentation, src/lclint.def
needed for linking and test-Makefiles.

14 files changed:
os2/BUILD.OS2 [new file with mode: 0644]
os2/Makefile.os2 [new file with mode: 0644]
os2/README.OS2 [new file with mode: 0644]
os2/makeos2.cmd [new file with mode: 0755]
os2/run_lclint.cmd [new file with mode: 0755]
src/Headers/constants.h
src/Makefile.os2
src/cpplib.c
src/cscanner.l
src/lclint.def [new file with mode: 0644]
test/Makefile-test.os2 [new file with mode: 0644]
test/rc3.lclintrc.os2 [new file with mode: 0644]
test/tests2.2/Makefile-tests2.2.os2 [new file with mode: 0644]
test/tests2.4/Makefile-tests2.4.os2 [new file with mode: 0644]

diff --git a/os2/BUILD.OS2 b/os2/BUILD.OS2
new file mode 100644 (file)
index 0000000..75e2257
--- /dev/null
@@ -0,0 +1,89 @@
+Building lclint:\r
+----------------\r
+\r
+This file is originally part of the binary distribution of lclint for OS/2.\r
+\r
+For building lclint for OS/2 you need the complete "original" source\r
+package (available e.g. via Dave Evans' lclint homepage) and maybe \r
+some more recent patches for the OS/2 version. The LCLint home page\r
+is at:\r
+\r
+  http://lclint.cs.virginia.edu/\r
+\r
+My fixes can be found at:\r
+\r
+  http://www.fh-wedel.de/pub/fh-wedel/staff/di/lclint/index.html\r
+\r
+Edit the makefile "Makefile.os2" and the compile batch "makeos2.cmd" \r
+in the "lclint-?.?\os2" directory. During make execution all important \r
+settings will be written to a config file read by any sub makefile. In\r
+any case you will have to set the variable `$BASEDIR' in Makefile.os2 \r
+and `%base%' in makeos2.cmd according to your setup.\r
+\r
+Then use the batch file makeos2.cmd from inside the os2/ directory\r
+to build lclint. The options to that batch file are:\r
+\r
+  makeos2 [--emx|-e|--gcc|-g|--icc|-i|--oldconf|-o|--test|-t|--package|-p]\r
+\r
+Like with make, this batch should be called from inside the os2\r
+directory. The options starting with "e" build LCLint using emx/gcc with \r
+debug code. The letter "g" stands for gcc using the OMF object format \r
+and optimization rather than debug code. For IBMs icc compiler use "i".\r
+Each of the above options will create a new configuration. To continue\r
+a build with an existing configuration use "o". Finally "t" runs the\r
+"quicktest" part of the test suite (other tests are not yet supported).\r
+\r
+Please, be aware that you need the flex library in order to build lclint.\r
+As far as I remember the OS/2 version of flex comes with this library for\r
+the emx/gcc compiler. If not, you will easily be able to compile it \r
+following the instructions from flex'es README.OS2 file.\r
+\r
+If you want to use IBM's compiler, you will probably not find the lib\r
+as easily as the whole flex package has so far only been ported for \r
+emx/gcc. However you can compile the lib with IBM's compiler, too. To\r
+do this, you will have to get the flex sources from one of the usual \r
+ftp sites and compile at least the library. \r
+\r
+To compile the flex library using IBM's VisualAge C++ compiler, you only\r
+need to perform the following steps:\r
+\r
+- enter the flex source directory.\r
+- enter "icc -c -Q -O libmain.c" and "icc -c -Q -O libyywrap.c"\r
+- enter "ilib fl.lib" from the command line (the library must not exist)\r
+  and "y", "+libmain.obj+libyywrap.obj" and "<enter>" from the ilib prompt.\r
+- copy fl.lib somewhere where it gets found, I suggest "ibmcpp\lib".\r
+\r
+When using emx/gcc you can either produce code using the OMF object format\r
+or use a.out. The latter has the consequence of needing emx.dll to run the \r
+binary and under certain circumstances being able to run it under DOS using \r
+emx.exe or rsx.exe as DOS extender (you may want to replace the "-g" switch\r
+by "-O3" in the compiler settings for optimization rather than debug code)\r
+in such a case. \r
+\r
+To create such a binary override the default settings in the makefile by \r
+invoking the following little batch (the default settings for using the \r
+a.out format defined in Makefile.os2 do *not* produce an executable that \r
+runs under DOS):\r
+\r
+    @echo off\r
+    if exist bin\lclint del bin\lclint\r
+    make all -f makefile.os2 "COMPILER=gcc-emx" "CC=gcc -O3" "E="\r
+    if errorlevel 1 goto end\r
+    cd bin\r
+    echo on\r
+    emxbind lclint -p\r
+    @echo off\r
+    cd ..\r
+    :end\r
+\r
+Please be aware that for debugging purposes the a.out format is the best \r
+choice. I did not succeed in debugging any single step of lclint using \r
+ipmd as it crashed each time I tried to load the lclint executable.\r
+\r
+The Makefile.os2 is currently configured to use flex and bison to generate \r
+some source files. If you do not have these tools on your system you should \r
+change the corresponding section to use the .der files shipping with the \r
+lclint sources.\r
+\r
+Herbert in September 2001\r
+\r
diff --git a/os2/Makefile.os2 b/os2/Makefile.os2
new file mode 100644 (file)
index 0000000..9cd2710
--- /dev/null
@@ -0,0 +1,285 @@
+##################################################\r
+###\r
+### Makefile for OS/2 version of LCLint\r
+###\r
+### designed for use with gmake (GNU make)\r
+###\r
+### based on David Evans' original makefile for Unix systems automatically\r
+###  generated by configure on a Linux system.\r
+###\r
+### configuration is set here and written to file config.inc included by\r
+###  other makefiles\r
+###\r
+### supported compilers are:\r
+###  emx/gcc\r
+###  IBM VisualAge C++ 3.0\r
+###\r
+### other system requirements:\r
+###  HPFS filesystem (long filenames).\r
+###\r
+### *NOTE*, before running "make" edit this file to fit your local settings!\r
+### ========================================================================\r
+###\r
+### Commands:\r
+###\r
+### make all\r
+###    builds a release version of lclint from scratch using optimizations\r
+###\r
+### This makefile uses gmake, the gnu version of make.\r
+###\r
+### Run gmake to build LCLint.\r
+###     gmake install to install.\r
+###\r
+\r
+###\r
+### lclint version and date:\r
+###\r
+\r
+LCL_VERSION=3.0.0.16\r
+LCL_DATE=25 Sep 2001\r
+\r
+# this gets written into the binary, add your name, your compiler settings\r
+#  etc. if you like.\r
+TODAY=Monday 25 Sep 19:40 MEST 2001\r
+ME=herbert\r
+MACHINE=i586\r
+COMPILE_MSG=\# define LCL_COMPILE \"Compiled using $(CC)\\n on OS/2 $(TODAY) $(MACHINE) by $(ME),\\n OS/2 specific subversion is 4\"\r
+\r
+### Directory containing system include files:\r
+\r
+SYSTEM_LIBDIR   = "\\\\usr\\\\include"\r
+\r
+### default preprocessor command:\r
+\r
+CPPCMD = "cpp "\r
+\r
+###\r
+### Select installation directories:\r
+###\r
+### The LIBDIR and IMPORTSDIR are compiled into the binary to \r
+### select the default LARCH_PATH and LCLIMPORTDIR, which can \r
+### also be overridden by environment variables.\r
+###\r
+### It may be a good idea to edit these variables not only in this\r
+### makefile but also in the header file src/Headers/local_constants.h\r
+### \r
+\r
+### directory for lclint libraries\r
+LIBDIR     = \\\\usr\\\\lib\\\\lclint\\\\lib\r
+\r
+### directory for lclint standard imports\r
+IMPORTSDIR = \\\\usr\\\\lib\\\\lclint\\\\imports\r
+\r
+### these are automatically set:\r
+\r
+SYSTEM_IMPORTSDIR = "$(IMPORTSDIR)"\r
+SYSTEM_LARCHPATH  = ".;$(LIBDIR)"\r
+\r
+### directory for lclint binary\r
+INSTALLDIR = \\usr\\bin\r
+\r
+### this should be the complete path for the directory where this\r
+### Makefile is, with no trailing / or spaces.\r
+\r
+BASEDIR = e:\\usr\\src\\lclint-$(LCL_VERSION)\r
+\r
+###\r
+### Then, run:\r
+###\r
+###    make\r
+###\r
+### I recommend doing this in an emacs shell (or buffered terminal) so\r
+### you can scroll through the output.\r
+###\r
+### This should (hopefully) work on most systems without further changes.\r
+###\r
+### If you do not have gcc, set CC = cc (or some other compiler)\r
+### later in this file. \r
+###\r
+### It should:\r
+###     o build lclint\r
+###     o put lclint in BASEDIR/bin/lclint\r
+###\r
+### If you have installed the test suite, then do:\r
+###\r
+###    make test\r
+###\r
+### to verify lclint.\r
+###\r
+\r
+###\r
+### If you wish to install lclint in some other directory, set these \r
+### variables, and do \r
+###\r
+###    make install\r
+###\r
+\r
+### installation command (I use emx GNUish utilities)\r
+CP = cp\r
+MV = mv\r
+CAT = type\r
+RM = rm\r
+INSTALL = cp\r
+INSTALLFLAGS =           \r
+ECHO = "echo.exe"\r
+\r
+###\r
+### end of installation variables\r
+###\r
+\r
+###\r
+### compiler --- gcc is recommended, but lclint has been compiled\r
+###              without changes using cc on several platforms.\r
+###\r
+\r
+# name of configuration:\r
+COMPILER=gcc-emx\r
+#COMPILER=gcc-os2\r
+#COMPILER=icc-os2\r
+\r
+# compile commands:\r
+ifeq ($(COMPILER), gcc-emx)\r
+ CC = gcc -g\r
+ CPPFLAGS=-I.\Headers -DSTDC_HEADERS=1 -DOS2\r
+ CFLAGS=-Wall \r
+ OFLAG=-o \r
+ LINKFLAGS = -lfl\r
+ O=.o\r
+ E=.exe\r
+else\r
+ ifeq ($(COMPILER), gcc-os2)\r
+  CC = gcc -Zsys -Zomf -O3\r
+  CPPFLAGS=-I.\Headers -DSTDC_HEADERS=1 -DOS2\r
+  CFLAGS=-Wall \r
+  OFLAG=-o \r
+  LINKFLAGS = lclint.def -lfl\r
+  O=.obj\r
+  E=.exe\r
+ else\r
+  ifeq ($(COMPILER), icc-os2)\r
+   # Shame! Normally no warnings should be turned off, but IBM's are\r
+   # so stupid they warn me about each llassert(). Let's check our\r
+   # code using lclint then develop it on gcc and then move to IBMC...\r
+   CC = icc -q -W2 -Dunlink=unlink -O+ -G5 -Gf+ -Gi+ -Gs+ \r
+   #CSet 2.01 needs this:\r
+   #-D__STDC__\r
+   CPPFLAGS=-I.\Headers -DSTDC_HEADERS=1 -DOS2 \r
+   CFLAGS=\r
+   OFLAG=-fe\r
+   LINKFLAGS = -B/noe setargv.obj fl.lib lclint.def\r
+   O=.obj\r
+   E=.exe\r
+  endif\r
+ endif\r
+endif\r
+\r
+###\r
+### do you have bison and/or flex?\r
+### (Note: yacc will probably not work; lex might work but is not recommended.)\r
+###\r
+\r
+BISON     = bison\r
+FLEX      = flex\r
+YFLAGS    = -v -t -d\r
+LFLAGS    =\r
+\r
+###\r
+### is the test suite available? (must be full path here)\r
+###\r
+\r
+TESTDIR   = $(BASEDIR)/test\r
+\r
+### \r
+### if this Makefile is used with one of the\r
+### standard installation packages, no changes should be \r
+### necessary below this line.\r
+###\r
+\r
+.PHONY: install dobinaries dolibraries doimports test \r
+\r
+###\r
+### set this to a different directory\r
+### to install binaries elsewhere\r
+###\r
+\r
+RELEASEDIR      = $(BASEDIR)/bin\r
+\r
+all: \r
+       @$(ECHO)\r
+       @$(ECHO) "Creating configuration file. Syntax error message can be ignored..."\r
+       @$(ECHO)\r
+       $(MAKE) -f Makefile.os2 --warn-undefined-variables configinc  \r
+       @$(ECHO)\r
+       @$(ECHO) "Creating local constants header file. Syntax error messages can be ignored..."\r
+       @$(ECHO)\r
+       $(MAKE) ARGV=$(ARGV) -f Makefile.os2 --directory=$(BASEDIR)\\src --warn-undefined-variables localconstants \r
+       @$(ECHO)\r
+       @$(ECHO) "Now building lclint executable file..."\r
+       @$(ECHO)\r
+       $(MAKE) -f Makefile.os2 --directory=$(BASEDIR)\\src --warn-undefined-variables\r
+       @$(ECHO)\r
+       @$(ECHO) "Now moving lclint executable file to bin directory..."\r
+       @$(ECHO)\r
+       $(MV) $(BASEDIR)\src\lclint$E $(RELEASEDIR)\lclint$E\r
+\r
+configinc:\r
+       $(ECHO) "CC=$(CC)" >config.inc\r
+       $(ECHO) "CFLAGS=$(CFLAGS)" >>config.inc\r
+       $(ECHO) "CPPFLAGS=$(CPPFLAGS)" >>config.inc\r
+       $(ECHO) "BISON=$(BISON)" >>config.inc\r
+       $(ECHO) "FLEX=$(FLEX)" >>config.inc\r
+       $(ECHO) "YFLAGS=$(YFLAGS)" >>config.inc\r
+       $(ECHO) "LFLAGS=$(LFLAGS)" >>config.inc\r
+       $(ECHO) "SYSTEM_LIBDIR=\"$(SYSTEM_LIBDIR)\"" >>config.inc\r
+       $(ECHO) "DEFAULT_LCLIMPORTDIR=\"$(SYSTEM_IMPORTSDIR)\"" >>config.inc\r
+       $(ECHO) "DEFAULT_LARCHPATH=\"$(SYSTEM_LARCHPATH)\"" >>config.inc\r
+       $(ECHO) "DEFAULT_CPPCMD=\"$(CPPCMD)\"" >>config.inc\r
+       $(ECHO) "LINKFLAGS=$(LINKFLAGS)" >>config.inc\r
+       $(ECHO) "O=$O" >>config.inc\r
+       $(ECHO) "E=$E" >>config.inc\r
+       $(ECHO) "OFLAG=$(OFLAG)lclint$E" >>config.inc\r
+       $(ECHO) "CAT=$(CAT)" >>config.inc\r
+       $(ECHO) "MV=$(MV)" >>config.inc\r
+       $(ECHO) "CP=$(CP)" >>config.inc\r
+       $(ECHO) "ECHO=\"$(ECHO)\"" >>config.inc\r
+       $(CP) $(BASEDIR)\src\Headers\herald.h $(BASEDIR)\src\Headers\herald.last\r
+       $(ECHO) "/* herald.h - created automatically from herald.os2 and Makefile.os2 */" >$(BASEDIR)\src\Headers\herald.h\r
+       $(ECHO) "/*@constant observer char *LCL_VERSION;@*/" >>$(BASEDIR)\src\Headers\herald.h\r
+       $(ECHO) "# define LCL_VERSION \"LCLint $(LCL_VERSION) --- $(LCL_DATE)\"" >>$(BASEDIR)\src\Headers\herald.h\r
+       $(ECHO) "/*@constant observer char *LCL_PARSE_VERSION;@*/" >>$(BASEDIR)\src\Headers\herald.h\r
+       $(ECHO) "# define LCL_PARSE_VERSION \"LCLint $(LCL_VERSION)\"" >>$(BASEDIR)\src\Headers\herald.h\r
+       $(ECHO) "/*@constant observer char *LCL_COMPILE;@*/" >>$(BASEDIR)\src\Headers\herald.h\r
+       $(ECHO) "$(COMPILE_MSG)" >>$(BASEDIR)\src\Headers\herald.h\r
+\r
+###\r
+### locations of standard LCLint files\r
+###\r
+### this should NOT have to be edited if you use the standard\r
+###    installation package\r
+\r
+LCLINTBINDIR = $(BASEDIR)/bin\r
+\r
+LCLINTLIB = $(BASEDIR)/lib\r
+LCLINTIMPORTS = $(BASEDIR)/imports\r
+\r
+###\r
+### uses recursive make calls directly, so installation\r
+### will continue even if there are errors!\r
+###\r
+\r
+install: \r
+       $(MAKE) dobinaries   -f Makefile.os2\r
+       $(MAKE) dolibraries  -f Makefile.os2\r
+       $(MAKE) doimports    -f Makefile.os2\r
+\r
+dobinaries:\r
+       $(INSTALL) $(INSTALLFLAGS) $(LCLINTBINDIR)\lclint$E $(INSTALLDIR)\r
+\r
+dolibraries:\r
+       -mkdir$E $(LIBDIR)\r
+       $(CP) $(LCLINTLIB)\\* $(LIBDIR)\r
+\r
+doimports:\r
+       -mkdir$E $(IMPORTSDIR)\r
+       $(CP) $(LCLINTIMPORTS)\\* $(IMPORTSDIR)\r
+\r
diff --git a/os2/README.OS2 b/os2/README.OS2
new file mode 100644 (file)
index 0000000..e61528c
--- /dev/null
@@ -0,0 +1,152 @@
+lclint 3.0.0.16 for OS/2\r
+========================\r
+\r
+This file is originally part of the binary distribution of lclint for OS/2.\r
+\r
+Contents:\r
+---------\r
+\r
+ Differences to the Unix versions\r
+ Installation\r
+ Bugs and known problems\r
+ Where to get\r
+ History\r
+ Afterword\r
+\r
+\r
+Differences to the Unix versions:\r
+---------------------------------\r
+\r
+1. lclint searches for the initialization file in the current directory \r
+   and additionally in the directory pointed to by the environment \r
+   variable "HOME" if set. \r
+\r
+2. For path specifications "\" can be used instead of "/". In most\r
+   cases any of both, even in combination are fine.\r
+\r
+3. lclint/2 will use the value of the environment variable TMP (if not set\r
+   TEMP) for creating and reading temporary files if possible. Else the\r
+   current directory is used.\r
+\r
+\r
+Installation:\r
+-------------\r
+\r
+For installing lclint there are four steps necessary:\r
+\r
+1. Place the executable file lclint.exe in some directory in your PATH.\r
+2. Install all that's in the "imports" and "lib" subdirectories somewhere\r
+   you like it. You will need a HPFS drive to install these files.\r
+3. Set the environment variable LARCH_PATH to the `lib' subdir in the \r
+   main LCLint directory, like:\r
+     set LARCH_PATH=d:\software\lclint-3.0.0.16\lib\r
+   Then set LCLIMPORTDIR to the `imports' subdir in the main LCLint\r
+   directory, like:\r
+     set LCLIMPORTDIR=d:\software\lclint-3.0.0.16\imports\r
+   You may want to add these statements to your your config.sys file \r
+   as soon as you've got the software working. \r
+4. If you want to use some standard settings different from what's built\r
+   in edit and place the configuration file `.lclintrc' somewhere lclint \r
+   can find it. This is the directory pointed to by the HOME environment\r
+   variable if set or else the directory containing the executable file.\r
+   It seems a good idea to put all global stuff into that file and all\r
+   project dependent information into another `.lclintrc' in the directory\r
+   containing the sources to be checked by lclint. lclint will first\r
+   read the global and then the local `.lclintrc'.\r
+\r
+For building lclint you will need the complete sources package. Untar that\r
+file. You need HPFS to compile the package because there are plenty of \r
+files with long filenames. Refer to the file BUILD.OS2 for further \r
+instructions. \r
+\r
+\r
+Bugs and known problems:\r
+------------------------\r
+\r
+There are a few things that still do not work properly. As lclint was\r
+originally developed on and for Unix systems e.g. path names differ.\r
+Currently all paths specified in the command line have to contain\r
+backslashes rather than slashes which will be quite normal for people\r
+with no Unix background anyway. Also not all tests work well yet, at\r
+the moment only the "quicktest" with a few changes is available.\r
+\r
+\r
+Where to get:\r
+-------------\r
+\r
+In any case future versions of lclint for OS/2 will be available from the\r
+lclint homepage at:\r
+ - http://lclint.cs.virginia.edu/\r
+\r
+I will try to upload the file to at least the following sites (the file \r
+should be located somewhere in the OS2/DEVELOP areas):\r
+ - ftp.cdrom.com\r
+ - ftp.hobbes.nmsu.edu\r
+ - ftp.leo.org\r
+I always put any fixes (even unofficial ones) to my private ftp directory\r
+at:\r
+ - ftp.fh-wedel.de/pub/fh-wedel/staff/herbert/lclint\r
+\r
+\r
+History:\r
+--------\r
+\r
+The following things specific to the OS/2 version of lclint have changed / \r
+fixed since the first official release:\r
+\r
+version 3.0.0.16:\r
+- Bugfixes.\r
+\r
+version 3.0.0.14:\r
+- first OS/2 version of the current alpha.\r
+- changed the name of the initialization file to `.lclintrc'.\r
+\r
+version 2.5m:\r
+- only some fixes mostly derived from the Win32 port.\r
+\r
+version 2.4b:\r
+- First official OS/2 release.\r
+- Switched from IBM's CSet++ 2.01 to VisualAge C++ 3.0.\r
+\r
+version 2.3i:\r
+- Due to my mistake the "HOME" environment variable was ignored even if it \r
+  was set.\r
+\r
+version 2.3h:\r
+- IBM's CSet++ is now used as default compiler instead of emx/gcc.\r
+- lclint compiled as a.out binary using emx/gcc now runs fine under DOS.\r
+- In the previous release some temporary files did not get removed properly.\r
+- Sometimes lclint delivered the names of temporary files rather than the\r
+  original source files when reporting errors.\r
+- Sometimes include files were not found.\r
+\r
+\r
+Due to the differences between Unix and OS/2 (file-I/O, standard directory\r
+structures etc.) there are still some more to expect!\r
+\r
+\r
+Afterword:\r
+----------\r
+\r
+I have not yet fully ported Makfiles / scripts for a full-featured test\r
+suite. The simple Makefile.os2 in the test/ directory allows checking\r
+the C sources belonging to the suite and looking at the output (or \r
+directing it to a file using "make -f Makefile.os2 >test.log 2>&1" or\r
+something similar. \r
+\r
+After having used lclint/2 on a few projects now I may say it has got \r
+more reliable. Still I do not know enough about it yet to be able to do  \r
+more sophisticated testing than just using it for my sources or running\r
+the (simplified) test suite. If you run across any OS/2-specific problems \r
+write me an email -- I will *try* to fix it. But, please, do not forget \r
+that I am *not* the author of lclint!\r
+\r
+You can reach me via Email or fido-netmail:\r
+\r
+Email: herbert@paulina.shnet.org (at home)\r
+       herbert@fh-wedel.de (at work)\r
+Fido:  2:240/5216.18\r
+\r
+Have fun!\r
+\r
+Martin "Herbert" Dietze\r
diff --git a/os2/makeos2.cmd b/os2/makeos2.cmd
new file mode 100755 (executable)
index 0000000..29fde7c
--- /dev/null
@@ -0,0 +1,62 @@
+@echo off\r
+setlocal\r
+set version=3.0.0.16\r
+set base=e:\usr\src\lclint-%version%\r
+if "%1"=="" goto icc\r
+if "%1"=="--icc" goto icc\r
+if "%1"=="-i" goto icc\r
+if "%1"=="--emx" goto emx\r
+if "%1"=="-e" goto emx\r
+if "%1"=="--gcc" goto gcc\r
+if "%1"=="-g" goto gcc\r
+if "%1"=="--oldconf" goto oldconf\r
+if "%1"=="-o" goto oldconf\r
+if "%1"=="--test" goto test\r
+if "%1"=="-t" goto test\r
+if "%1"=="--package" goto package\r
+if "%1"=="-p" goto package\r
+"echo.exe" "usage: makeos2 [--emx|-e|--gcc|-g|--icc|-i|--oldconf|-o|--test|-t|--package|-p]"\r
+goto end\r
+\r
+:emx\r
+set COMPILER=gcc-emx\r
+goto initial\r
+\r
+:gcc\r
+set COMPILER=gcc-os2\r
+goto initial\r
+\r
+:icc\r
+set COMPILER=icc-os2\r
+goto initial\r
+\r
+:initial\r
+sh -c "export TODAY=`date.exe`; export LCL_DATE=`date.exe | cut -d ' ' -f 2,3,6`; make -e -f Makefile.os2 %2 %3 %4 %5 %6 %7 %8 %9"\r
+goto end\r
+\r
+:oldconf\r
+make -f Makefile.os2 --directory=../src --warn-undefined-variables %2 %3 %4 %5 %6 %7 %8 %9 \r
+if errorlevel 0 mv ..\src\lclint.exe ..\bin\r
+goto end\r
+\r
+:test\r
+set LARCH_PATH=%base%\lib\r
+set LCLIMPORTDIR=%base%\imports\r
+cd ..\test\r
+echo it's %LARCH_PATH% and %LCLIMPORTDIR%\r
+make LCLINT=%base%\bin\lclint %2 -e -f Makefile-test.os2\r
+cd ..\os2\r
+goto end\r
+\r
+:package\r
+cd %base%\..\r
+rm -f lclint-%version%-os2-*.tar*\r
+tar cvf lclint-%version%-os2-bin.tar lclint-%version%\bin lclint-%version%\imports lclint-%version%\lib lclint-%version%\os2 lclint-%version%\test lclint-%version%\BUFFERCHECKING lclint-%version%\LICENSE lclint-%version%\README\r
+tar cvf lclint-%version%-os2-all.tar lclint-%version%\r
+cd \export\lclint\r
+tar cvf %base%\..\lclint-%version%-os2-add.tar lclint-%version%\r
+gzip %base%\..\lclint-%version%-os2-*.tar\r
+goto end\r
+\r
+:end\r
+endlocal\r
diff --git a/os2/run_lclint.cmd b/os2/run_lclint.cmd
new file mode 100755 (executable)
index 0000000..35fc3d9
--- /dev/null
@@ -0,0 +1,12 @@
+@echo off\r
+rem *****************************************************************\r
+rem run LCLint from the source\os2 directory with proper environment\r
+rem *****************************************************************\r
+setlocal\r
+set base=e:\usr\src\lclint-3.0.0.16\r
+set LARCH_PATH=%base%\lib\r
+set LCLIMPORTDIR=%base%\imports\r
+set LCLBINARY=%base%\bin\lclint.exe \r
+echo it's %LCLBINARY%, %LARCH_PATH% and %LCLIMPORTDIR%\r
+%LCLBINARY% %1 %2 %3 %4 %5 %6 %7 %8 %9\r
+endlocal\r
index bfe9bb9bcc9f0540887392a9e5aef771876e6b86..2a9a4aeb96968f738c473eca5279bef4eaa97bd5 100644 (file)
@@ -16,7 +16,7 @@
 # ifndef CONSTANTS_H
 # define CONSTANTS_H
 
-# if defined(MSDOS) || defined(OS2)
+# if defined(MSDOS) 
 /*@constant observer char *RCFILE; @*/
 # define RCFILE         "lclint.rc"
 # else
index e3c930a1a54734b009031e56f1089167c1354e48..c5bc368065a0ecbb5888b2a8d2e75163ea6a9c1c 100644 (file)
@@ -21,7 +21,7 @@ O=.o
 E=
 
 
-include ../config.inc
+include ../os2/config.inc
 
 .SUFFIXES:
 .SUFFIXES: $E $O .h .c .l .check
@@ -30,37 +30,51 @@ include ../config.inc
 ### object files needed for building lclint:
 ###  note that there is no dependency checking done!
 ###
-OBJ=abstract$O aliasChecks$O aliasTable$O cgrammar$O checking$O \
-    clabstract$O clause$O clauseStack$O context$O cprim$O cscanner$O \
-    cstring$O cstringSList$O ctype$O ctypeList$O cvar$O \
-    declaratorInvNodeList$O declaratorNodeList$O ekind$O enumNameList$O \
-    enumNameSList$O exprChecks$O exprNode$O exprNodeList$O \
-    exprNodeSList$O fcnNodeList$O fileIdList$O fileStack$O fileTable$O \
-    fileloc$O filelocList$O filelocStack$O flagMarker$O flagMarkerList$O \
-    flags$O general$O globSet$O globals$O guardSet$O hashTable$O \
-    idDecl$O idDeclList$O importNodeList$O imports$O indxMap$O \
-    initDeclNodeList$O intSet$O interfaceNodeList$O lclctypes$O lclinit$O \
-    lcllib$O lclscan$O lclscanline$O lclsyntable$O lcltokentable$O \
-    letDeclNodeList$O lh$O llerror$O llgrammar$O llmain$O lltok$O \
-    lslOpList$O lslOpSet$O lslinit$O lslparse$O lsymbol$O lsymbolList$O \
-    lsymbolSet$O ltoken$O ltokenList$O macrocache$O mapping$O message$O \
-    messageLog$O multiVal$O nameChecks$O osd$O out$O pairNodeList$O \
-    paramNodeList$O pcpp$O programNodeList$O qtype$O qual$O qualList$O \
-    quantifierNodeList$O replaceNodeList$O sRef$O sRefSet$O sRefSetList$O \
-    sRefTable$O scan$O scanline$O shift$O sigNodeSet$O signature$O \
-    sort$O sortList$O sortSet$O sortSetList$O source$O specialClauses$O \
-    stDeclNodeList$O storeRefNodeList$O structNames$O symtable$O  \
-    syntable$O termNodeList$O tokentable$O traitRefNodeList$O typeIdSet$O \
+FIRSTOBJ=cgrammar$O llgrammar$O signature$O
+OBJ=$(FIRSTOBJ) abstract$O aliasTable$O annotationInfo$O annotationTable$O  \
+    checking$O clabstract$O clause$O clauseStack$O constraint$O \
+    constraintExpr$O constraintExprData$O constraintGeneration$O \
+    constraintList$O constraintOutput$O constraintResolve$O constraintTerm$O \
+    context$O cpperror$O cppexp$O cpphash$O cpplib$O cppmain$O cprim$O \
+    cscanner$O cstring$O cstringList$O cstringSList$O cstringTable$O ctype$O \
+    ctypeList$O cvar$O declaratorInvNodeList$O declaratorNodeList$O ekind$O \
+    enumNameList$O enumNameSList$O exprChecks$O exprData$O exprNode$O \
+    exprNodeList$O exprNodeSList$O fcnNodeList$O fileLib$O fileIdList$O \
+    fileTable$O fileloc$O filelocList$O filelocStack$O flagMarker$O \
+    flagMarkerList$O flagSpec$O flags$O forjunk$O functionClause$O \
+    functionClauseList$O functionConstraint$O general$O genericTable$O \
+    globalsClause$O globSet$O globals$O guardSet$O idDecl$O idDeclList$O \
+    importNodeList$O imports$O initDeclNodeList$O inputStream$O intSet$O \
+    interfaceNodeList$O lclctypes$O lclinit$O lcllib$O lclscan$O \
+    lclscanline$O lclsyntable$O lcltokentable$O letDeclNodeList$O lh$O \
+    llerror$O llmain$O lltok$O lslOpList$O lslOpSet$O lslinit$O \
+    lslparse$O lsymbol$O lsymbolList$O lsymbolSet$O ltoken$O ltokenList$O \
+    macrocache$O mapping$O message$O messageLog$O metaStateConstraint$O \
+    metaStateConstraintList$O metaStateExpression$O metaStateInfo$O \
+    metaStateSpecifier$O metaStateTable$O modifiesClause$O mtAnnotationDecl$O \
+    mtAnnotationList$O mtAnnotationsNode$O mtContextNode$O \
+    mtDeclarationNode$O mtDeclarationPiece$O mtDeclarationPieces$O \
+    mtDefaultsDecl$O mtDefaultsDeclList$O mtDefaultsNode$O mtLoseReference$O \
+    mtLoseReferenceList$O mtMergeClause$O mtMergeClauseList$O mtMergeItem$O \
+    mtMergeNode$O mtTransferAction$O mtTransferClause$O \
+    mtTransferClauseList$O mtValuesNode$O mtgrammar$O mtreader$O mtscanner$O \
+    mttok$O multiVal$O nameChecks$O osd$O pairNodeList$O paramNodeList$O \
+    programNodeList$O qtype$O qual$O qualList$O quantifierNodeList$O \
+    randomNumbers$O reader$O replaceNodeList$O sRef$O sRefSet$O sRefSetList$O \
+    sRefTable$O scan$O scanline$O shift$O sigNodeSet$O \
+    sort$O sortList$O sortSet$O sortSetList$O stateClause$O stateClauseList$O \
+    stateCombinationTable$O stateInfo$O stateValue$O stDeclNodeList$O \
+    storeRefNodeList$O structNames$O symtable$O syntable$O termNodeList$O \
+    tokentable$O traitRefNodeList$O transferChecks$O typeIdSet$O \
     typeNameNodeList$O uentry$O uentryList$O usymIdSet$O usymtab$O \
-    usymtab_interface$O varDeclarationNodeList$O varKinds$O varNodeList$O \
-    ynm$O 
-
+    usymtab_interface$O valueTable$O varDeclarationNodeList$O varKinds$O \
+    varNodeList$O warnClause$O ynm$O 
 
 ###
 ### main (and only) target: lclint with all optimizations.
 ###
 
-all : lclint$E
+all: Headers\\flag_codes.gen lclint$E
 lclint$E : $(OBJ) 
        $(CC) $(OFLAG) $(OBJ) $(LINKFLAGS)
 
@@ -71,15 +85,15 @@ lclint$E : $(OBJ)
 localconstants:
        cmd /c if exist Headers\local_constants.last del Headers\local_constants.last
        cmd /c if exist Headers\local_constants.h ren Headers\local_constants.h local_constants.last
-       echo /* local_constants.h - created automatically by gmake localconstants */ > Headers\local_constants.h
-       echo /*@constant observer char *DEFAULT_CPPCMD;@*/ >> Headers\local_constants.h 
-       echo # define DEFAULT_CPPCMD $(DEFAULT_CPPCMD) >> Headers\local_constants.h
-       echo /*@constant observer char *SYSTEM_LIBDIR;@*/ >> Headers\local_constants.h 
-       echo # define SYSTEM_LIBDIR $(SYSTEM_LIBDIR) >> Headers\local_constants.h 
-       echo /*@constant observer char *DEFAULT_LARCHPATH;@*/ >> Headers\local_constants.h 
-       echo # define DEFAULT_LARCHPATH $(DEFAULT_LARCHPATH) >> Headers\local_constants.h 
-       echo /*@constant observer char *DEFAULT_LCLIMPORTDIR;@*/ >> Headers\local_constants.h 
-       echo # define DEFAULT_LCLIMPORTDIR $(DEFAULT_LCLIMPORTDIR) >> Headers\local_constants.h 
+       $(ECHO) "/* local_constants.h - created automatically by gmake localconstants */" > Headers\local_constants.h
+       $(ECHO) "/*@constant observer char *DEFAULT_CPPCMD;@*/" >> Headers\local_constants.h 
+       $(ECHO) -E "# define DEFAULT_CPPCMD \"$(DEFAULT_CPPCMD)\"" >> Headers\local_constants.h
+       $(ECHO) "/*@constant observer char *SYSTEM_LIBDIR;@*/" >> Headers\local_constants.h 
+       $(ECHO) -E "# define SYSTEM_LIBDIR \"$(SYSTEM_LIBDIR)\"" >> Headers\local_constants.h 
+       $(ECHO) "/*@constant observer char *DEFAULT_LARCHPATH;@*/" >> Headers\local_constants.h 
+       $(ECHO) -E "# define DEFAULT_LARCHPATH \"$(DEFAULT_LARCHPATH)\"" >> Headers\local_constants.h 
+       $(ECHO) "/*@constant observer char *DEFAULT_LCLIMPORTDIR;@*/" >> Headers\local_constants.h 
+       $(ECHO) -E "# define DEFAULT_LCLIMPORTDIR \"$(DEFAULT_LCLIMPORTDIR)\"" >> Headers\local_constants.h 
 
 ###
 ### grammars
@@ -94,7 +108,7 @@ signature.c : signature.c.der signature.y
 ifdef BISON
        $(BISON) $(YFLAGS) -p lsl signature.y
        $(CAT) bison.head signature.tab.c > signature.c
-       $(MV) Headers\signature_gen.h Headers\signature_gen.bak
+       -$(MV) Headers\signature_gen.h Headers\signature_gen.bak
        $(CAT) bison.head signature.tab.h > Headers\signature_gen.h
 else
        (CP) signature.c.der signature.c
@@ -104,7 +118,7 @@ cgrammar.c : cgrammar.c.der cgrammar.y
 ifdef BISON
        $(BISON) $(YFLAGS) cgrammar.y
        $(CAT) bison.head cgrammar.tab.c > cgrammar.c
-       $(MV) Headers\cgrammar_tokens.h Headers\cgrammar_tokens.bak
+       -$(MV) Headers\cgrammar_tokens.h Headers\cgrammar_tokens.bak
        $(CAT) bison.head cgrammar.tab.h > Headers\cgrammar_tokens.h
 else
        $(CP) cgrammar.c.der cgrammar.c
@@ -116,9 +130,9 @@ llgrammar.c  : llgrammar.c.der llgrammar.y
 ifdef BISON
        $(BISON) $(YFLAGS) -p yl llgrammar.y
        $(CAT) bison.head llgrammar.tab.c > llgrammar.c
-       $(MV) Headers\llgrammar_gen2.h Headers\llgrammar_gen2.bak
+       -$(MV) Headers\llgrammar_gen2.h Headers\llgrammar_gen2.bak
        $(CAT) bison.head llgrammar.tab.h > Headers\llgrammar_gen2.h
-       $(MV) Headers\llgrammar_gen.h Headers\llgrammar_gen.bak
+       -$(MV) Headers\llgrammar_gen.h Headers\llgrammar_gen.bak
        $(CAT) bison.head llgrammar.tab.h > Headers\llgrammar_gen.h
 else
        $(CP) llgrammar.c.der llgrammar.c
@@ -132,6 +146,25 @@ else
        $(CP) cscanner.c.der cscanner.c
 endif
 
+###
+### compile without warnings
+### 
+signature.o : signature.c
+       $(CC) $(CPPFLAGS) -c $*.c
+
+cgrammar.o : cgrammar.c
+       $(CC) $(CPPFLAGS) -c $*.c
+
+cscanner.o : cscanner.c
+       $(CC) $(CPPFLAGS) -c $*.c
+
+mtgrammar.o : mtgrammar.c
+       $(CC) $(CPPFLAGS) -c $*.c
+
+llgrammar.o : llgrammar.c
+       $(CC) $(CPPFLAGS) -c $*.c
+
+
 ###
 ### header files dependant on grammars
 ###
@@ -140,6 +173,14 @@ Headers\signature2.h : signature.c
 Headers\cgrammar2.h : cgrammar.c
 Headers\llgrammar.h : llgrammar.c
 
+###
+### generated headers
+###
+
+Headers\\flag_codes.gen: flags.def
+       grep "FLG_" $< >$@
+       touch flags.c
+
 ###
 ### defaults
 ###
@@ -148,7 +189,7 @@ Headers\llgrammar.h : llgrammar.c
 SINGLEFLAGS = +neverinclude -supcounts +partial -showsummary -load lclint.lcd
 
 .c$O:
-       $(CC) $(CPPFLAGS) -c $*.c 
+       $(CC) $(CFLAGS) $(CPPFLAGS) -c $*.c 
 
 ###
 ### cleaning
@@ -184,4 +225,3 @@ lint:
 
 
 
-
index b12e4f7feebf528cb6ea22e9b162345500c006a6..8a069f098e4061b063e799cddd0c24acf743ad3c 100644 (file)
-/*
-See
-http://src.openresources.com/debian/src/devel/HTML/S/altgcc_2.7.2.2.orig%20altgcc-2.7.2.2.orig%20protoize.c.html
-static char *
-abspath (cwd, rel_filename)
-
-*/
-
-/*!!!!
-*** cpplib.c.old Tue Nov 28 2000 09:04:09 AM
---- cpplib.c Tue Nov 28 2000 08:55:18 AM
-***************
-*** 5715,5722 ****
-     c2 = cppReader_peekC (pfile)
-     if (c2 != '\n'
-       goto randomchar
-!    token = CPP_HSPACE
-!    goto op2any
---- 5714,5723 ----
-          case '\\'
-     c2 = cppReader_peekC (pfile)
-     if (c2 != '\n'
-       goto randomchar
-!    cppReader_forward (pfile, 1)
-!    pfile->lineno++
-!    return CPP_HSPACE
-  
-   case '\n'
-     cppReader_putChar (pfile, c)
-
-
-Carl J. Appellof ( mailto:cappello@legato.com <mailto:cappello@legato.com> )
-*/ /*@i8@*/
-
-/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
-**         Massachusetts Institute of Technology
-**
-** This program is free software; you can redistribute it and/or modify it
-** under the terms of the GNU General Public License as published by the
-** Free Software Foundation; either version 2 of the License, or (at your
-** option) any later version.
-** 
-** This program is distributed in the hope that it will be useful, but
-** WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** General Public License for more details.
-** 
-** The GNU General Public License is available from http://www.gnu.org/ or
-** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-** MA 02111-1307, USA.
-**
-** For information on lclint: lclint-request@cs.virginia.edu
-** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.cs.virginia.edu
-*/
-/*
-** cpplib.c
-*/
-/*
-   Copyright (C) 1986, 87, 89, 92-6, 1997 Free Software Foundation, Inc.
-   Contributed by Per Bothner, 1994-95.
-   Based on CCCP program by Paul Rubin, June 1986
-   Adapted to ANSI C, Richard Stallman, Jan 1987
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them.   Help stamp out software-hoarding!  */
-
-/*
- * Herbert 06/12/2000:
- * - OS2 drive specs like WIN32
- * - Includes for IBMs OS/2 compiler
- */
-
-# include <ctype.h>
-# include <stdio.h>
-# include <signal.h>
-# ifdef __STDC__
-# include <stdlib.h>
-# endif
-
-# include <string.h>
-
-# if !(defined (WIN32) || defined (OS2) && defined (__IBMC__))
-# include <unistd.h>
-# endif
-
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-
-# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
-# include <io.h>
-# include <sys/utime.h>                /* for __DATE__ and __TIME__ */
-# include <time.h>
-# else
-# ifndef VMS
-# ifndef USG
-# include <time.h> /* Reported by Paul Smith */
-# include <sys/time.h>
-# include <sys/resource.h>
-# else
-# include <sys/times.h>
-# include <time.h>
-# include <fcntl.h>
-# endif /* USG */
-# endif /* not VMS */
-# endif /* not WIN32 */
-
-/* This defines "errno" properly for VMS, and gives us EACCES.  */
-# include <errno.h>
-
-# include "lclintMacros.nf"
-# include "llbasic.h"
-# include "lcllib.h"
-# include "cpplib.h"
-# include "cpperror.h"
-# include "cpphash.h"
-# include "cppexp.h"
-# include "version.h"
-# include "portab.h"
-# include "osd.h"
-
-/*
-** This is really kludgey code...
-*/
-
-/*@+boolint@*/
-/*@+charint@*/
-
-#define NO_SHORTNAMES
-
-# ifdef open
-# undef open
-# undef read
-# undef write
-# endif /* open */
-
-/*@constant int IMPORT_FOUND@*/
-# define IMPORT_FOUND -2
-
-/*@constant int SKIP_INCLUDE@*/
-# define SKIP_INCLUDE IMPORT_FOUND
-
-/*@constant unused int IMPORT_NOT_FOUND@*/
-# define IMPORT_NOT_FOUND -1
-
-#ifndef STDC_VALUE
-/*@constant unused int STDC_VALUE@*/
-#define STDC_VALUE 1
-#endif
-
-/* By default, colon separates directories in a path.  */
-#ifndef PATH_SEPARATOR
-/*@constant char PATH_SEPARATOR@*/
-#define PATH_SEPARATOR ':'
-#endif
-
-static void parse_name (cppReader *, int);
-
-static int cpp_openIncludeFile (char *p_filename)
-     /*@modifies fileSystem @*/ ;
-
-static void cpp_setLocation (cppReader *p_pfile)
-     /*@modifies g_currentloc@*/ ;
-
-static enum cpp_token cpp_handleComment (cppReader *p_pfile,
-                                        struct parse_marker *p_smark)
-     /*@modifies p_pfile, p_smark@*/;
-
-static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@*/ ;
-
-static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ;
-
-#ifndef O_RDONLY
-#define O_RDONLY 0
-#endif
-
-/* Symbols to predefine.  */
-
-#ifdef CPP_PREDEFINES
-static /*@observer@*/ char *predefs = CPP_PREDEFINES;
-#else
-static /*@observer@*/ char *predefs = "";
-#endif
-
-/* We let tm.h override the types used here, to handle trivial differences
-   such as the choice of unsigned int or long unsigned int for size_t.
-   When machines start needing nontrivial differences in the size type,
-   it would be best to do something here to figure out automatically
-   from other information what type to use.  */
-
-/* The string value for __SIZE_TYPE__.  */
-
-#ifndef SIZE_TYPE
-/*@constant observer char *SIZE_TYPE@*/
-#define SIZE_TYPE "long unsigned int"
-#endif
-
-/* The string value for __PTRDIFF_TYPE__.  */
-
-#ifndef PTRDIFF_TYPE
-/*@constant observer char *PTRDIFF_TYPE@*/
-#define PTRDIFF_TYPE "long int"
-#endif
-
-/* The string value for __WCHAR_TYPE__.  */
-
-#ifndef WCHAR_TYPE
-/*@constant observer char *WCHAR_TYPE@*/
-#define WCHAR_TYPE "int"
-#endif
-
-/* The string value for __USER_LABEL_PREFIX__ */
-
-#ifndef USER_LABEL_PREFIX
-/*@constant observer char *USER_LABEL_PREFIX@*/
-#define USER_LABEL_PREFIX ""
-#endif
-
-/* The string value for __REGISTER_PREFIX__ */
-
-#ifndef REGISTER_PREFIX
-/*@constant observer char *REGISTER_PREFIX@*/
-#define REGISTER_PREFIX ""
-#endif
-
-/* table to tell if char can be part of a C identifier.  */
-static bool is_idchar[256];
-/* table to tell if char can be first char of a c identifier.  */
-static bool is_idstart[256];
-/* table to tell if c is horizontal space.  */
-static bool is_hor_space[256];
-/* table to tell if c is horizontal or vertical space.  */
-static bool is_space[256];
-
-static /*@exposed@*/ /*@null@*/ cppBuffer *
-cppReader_getBuffer (/*@special@*/ cppReader *p_pfile)
-     /*@uses p_pfile->buffer@*/
-     /*@modifies nothing@*/ ;
-
-/*@notfunction@*/
-# define SKIP_WHITE_SPACE(p) do { /*@access cstring@*/ while (is_hor_space[(int) *(p)]) { (p)++; } } /*@noaccess cstring@*/ while (0)
-
-/*@notfunction@*/
-# define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*(p)]) { (p)++; } } while (0)
-
-static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ;
-
-/*@function static int cppBuffer_get (sef cppBuffer *p_b) modifies *p_b ; @*/
-# define cppBuffer_get(BUFFER) \
-  ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
-
-/* Append string STR (of length N) to PFILE's output buffer.  Make space. */
-/*@function static void cppReader_puts (sef cppReader *p_file, char *p_str, sef size_t p_n)
-                     modifies *p_file; @*/
-# define cppReader_puts(PFILE, STR, N) \
-  cppReader_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N)
-
-/* Append character CH to PFILE's output buffer.  Assume sufficient space. */
-
-/*@function static void cppReader_putCharQ (cppReader *p_file, char p_ch)
-                    modifies *p_file; @*/
-# define cppReader_putCharQ(PFILE, CH) (*(PFILE)->limit++ = (CH))
-
-/* Append character CH to PFILE's output buffer.  Make space if need be. */
-
-/*@function static void cppReader_putChar (sef cppReader *p_file, char p_ch)
-                    modifies *p_file; @*/
-#define cppReader_putChar(PFILE, CH) (cppReader_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH))
-
-/* Make sure PFILE->limit is followed by '\0'. */
-/*@function static void cppReader_nullTerminateQ (cppReader *p_file)
-      modifies *p_file; @*/
-
-#define cppReader_nullTerminateQ(PFILE) (*(PFILE)->limit = 0)
-
-/*@function static void cppReader_nullTerminate (sef cppReader *p_file)
-                           modifies *p_file; @*/
-# define cppReader_nullTerminate(PFILE) \
-  (cppReader_reserve (PFILE, (size_t) 1), *(PFILE)->limit = 0)
-
-/*@function static void cppReader_adjustWritten (cppReader *p_file, size_t)
-                           modifies *p_file; @*/
-#define cppReader_adjustWritten(PFILE,DELTA) ((PFILE)->limit += (DELTA))
-
-/*@function static bool cppReader_isC89 (cppReader *) modifies nothing; @*/
-#define cppReader_isC89(PFILE) (CPPOPTIONS(PFILE)->c89)
-
-/*@function static observer char *cppReader_wcharType (cppReader *)
-     modifies nothing; @*/
-
-# define cppReader_wcharType(PFILE) \
-  (CPPOPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE)
-
-static void cppBuffer_forward (cppBuffer *p_buf, int p_n) /*@modifies *p_buf@*/ ;
-
-/*@function static void cppReader_forward (cppReader *p_pfile, int) modifies *p_pfile; @*/
-# define cppReader_forward(pfile, N) \
-  (cppBuffer_forward (cppReader_getBufferSafe (pfile), (N)))
-
-/*@function static int cppReader_getC (cppReader *p_pfile) modifies *p_pfile; @*/
-# define cppReader_getC(pfile)   (cppBuffer_get (cppReader_getBufferSafe (pfile)))
-
-/*@function static int cppReader_peekC (cppReader *) modifies nothing;@*/
-# define cppReader_peekC(pfile)  (cppBufPeek (cppReader_getBufferSafe (pfile)))
-
-/* Move all backslash-newline pairs out of embarrassing places.
-   Exchange all such pairs following BP
-   with any potentially-embarrassing characters that follow them.
-   Potentially-embarrassing characters are / and *
-   (because a backslash-newline inside a comment delimiter
-   would cause it not to be recognized).  */
-
-/*@notfunction@*/
-# define NEWLINE_FIX \
-   do { while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n') { cppReader_forward (pfile, 2); } } while(FALSE)
-
-     /* Same, but assume we've already read the potential '\\' into C.  */
-/*@notfunction@*/
-# define NEWLINE_FIX1(C) do { \
-     while ((C) == '\\' && cppReader_peekC (pfile) == '\n') { cppReader_forward (pfile, 1); (C) = cppReader_getC (pfile); }\
-                                                                          } while(0)
-
-static void parseSetMark (/*@out@*/ struct parse_marker *,
-                         cppReader *);
-static void parseClearMark (struct parse_marker *);
-static void parseGotoMark (struct parse_marker *, cppReader *);
-static void parseMoveMark (struct parse_marker *, cppReader *);
-
-/* If we have a huge buffer, may need to cache more recent counts */
-static /*@exposed@*/ char *cppLineBase (/*@sef@*/ cppBuffer *);
-
-static /*@exposed@*/ /*@null@*/ cppBuffer *
-   cppReader_pushBuffer (cppReader *p_pfile,
-                        /*@owned@*/ /*@null@*/ char *, size_t)
-     /*@modifies p_pfile@*/ ;
-
-static void cppReader_appendIncludeChain
-(cppReader *p_pfile,
- /*@keep@*/ struct file_name_list *p_first,
- /*@dependent@*/ struct file_name_list *p_last);
-
-static void cppReader_macroCleanup (cppBuffer *p_pbuf, cppReader *p_pfile);
-static enum cpp_token cppReader_nullUnderflow (/*@unused@*/ cppReader *p_pfile);
-
-static void cppReader_nullCleanup (/*@unused@*/ cppBuffer *p_pbuf,
-                                  /*@unused@*/ cppReader *p_pfile);
-
-static void cppReader_fileCleanup (cppBuffer *p_pbuf,
-                                  /*@unused@*/ cppReader *p_pfile);
-
-static int cppReader_handleDirective (cppReader *p_pfile);
-
-static void cppReader_scanBuffer (cppReader *p_pfile);
-
-# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
-
-/*
-** WIN32 (at least the VC++ include files) does not define mode_t.
-*/
-
-/*@-incondefs@*/ /*@-czechtypes@*/
-typedef unsigned int mode_t;
-/*@=incondefs@*/ /*@=czechtypes@*/
-
-# endif
-
-static int file_size_and_mode (int p_fd, /*@out@*/ mode_t *p_mode_pointer,
-                              /*@out@*/ size_t *p_size_pointer);
-static int safe_read (int p_desc, /*@out@*/ char *p_ptr, int p_len);
-
-
-/*
-** cppBuffer_isMacro is true if the buffer contains macro expansion.
-** (Note that it is false while we're expanding marco *arguments*.)
-*/
-
-static bool cppBuffer_isMacro (/*@null@*/ cppBuffer *) /*@*/ ;
-
-static void path_include (cppReader *p_pfile, char *p_path)
-     /*@modifies p_pfile@*/ ;
-
-static void initialize_builtins (cppReader *p_pfile)
-     /*@modifies p_pfile@*/ ;
-
-static void initialize_char_syntax (struct cppOptions *p_opts) ;
-
-static int /*@alt void@*/ finclude (cppReader *p_pfile, int p_f,
-                                   cstring p_fname,
-                                   bool p_system_header_p,
-                                   /*@dependent@*/ /*@null@*/ struct file_name_list *p_dirptr);
-
-static void validate_else (cppReader *p_pfile, cstring p_directive);
-
-static void conditional_skip (cppReader *p_pfile, int p_skip,
-                             enum node_type p_type,
-                             /*@dependent@*/ /*@null@*/ char *p_control_macro);
-
-static HOST_WIDE_INT eval_if_expression (cppReader *p_pfile,
-                                        char *p_buf,
-                                        int p_length);
-
-static void skip_if_group (cppReader *p_pfile, int p_any);
-
-static bool comp_def_part (bool p_first, char *p_beg1, int p_len1,
-                          char *p_beg2, int p_len2, bool p_last);
-
-#ifdef abort
-extern void fancy_abort ();
-#endif
-
-static bool redundant_include_p (cppReader *p_pfile, /*@null@*/ cstring p_name);
-static bool is_system_include (cppReader *p_pfile, cstring p_filename);
-
-static /*@observer@*/ /*@null@*/ struct file_name_map *
-read_name_map (cppReader *p_pfile, cstring p_dirname);
-
-static cstring read_filename_string (int p_ch, /*:open:*/ FILE *p_f);
-
-static int open_include_file (cppReader *p_pfile,
-                             /*@owned@*/ cstring p_fname,
-                             /*@null@*/ struct file_name_list *p_searchptr);
-
-static void push_macro_expansion (cppReader *,
-                                 /*@owned@*/ char *, size_t,
-                                 /*@dependent@*/ hashNode);
-
-/* Last arg to output_line_command.  */
-enum file_change_code {
-  same_file, enter_file, leave_file
-};
-
-/* `struct directive' defines one #-directive, including how to handle it.  */
-
-struct directive {
-  int length;                  /* Length of name */
-  /*@null@*/ int (*func)();    /* Function to handle directive */
-  /*@observer@*/ cstring name; /* Name of directive */
-  enum node_type type;         /* Code which describes which directive.  */
-  bool command_reads_line;      /* One if rest of line is read by func.  */
-  bool traditional_comments;   /* Nonzero: keep comments if -traditional.  */
-  bool pass_thru;              /* Copy preprocessed directive to output file.*/
-};
-
-/* These functions are declared to return int instead of void since they
-   are going to be placed in a table and some old compilers have trouble with
-   pointers to functions returning void.  */
-
-static int do_define (cppReader *, /*@null@*/ struct directive *, 
-                     char *, char *);
-static int do_defineAux (cppReader *, /*@null@*/ struct directive *,
-                        char *, char *, bool);
-     
-static int do_line (cppReader *, /*@null@*/ struct directive *);
-static int do_include (cppReader *, struct directive *, char *, char *);
-static int do_undef (cppReader *, struct directive *, char *, char *);
-static int do_error (cppReader *, struct directive *, char *, char *);
-static int do_pragma (cppReader *, struct directive *, char *, char *);
-static int do_ident (cppReader *, struct directive *, char *, char *);
-static int do_if (cppReader *, struct directive *, char *, char *);
-static int do_xifdef (cppReader *, struct directive *, char *, char *);
-static int do_else (cppReader *, struct directive *, char *, char *);
-static int do_elif (cppReader *, struct directive *, char *, char *);
-static int do_endif (cppReader *, struct directive *, char *, char *);
-static int do_warning (cppReader *, struct directive *, char *, char *);
-
-/* If a buffer's dir field is SELF_DIR_DUMMY, it means the file was found
-   via the same directory as the file that #included it.  */
-
-/*@constant observer struct file_name_list *SELF_DIR_DUMMY@*/
-#define SELF_DIR_DUMMY ((struct file_name_list *) (~0))
-
-/* #include "file" looks in source file dir, then stack.  */
-/* #include <file> just looks in the stack.  */
-/* -I directories are added to the end, then the defaults are added.  */
-
-/*@access cstring@*/
-
-static struct default_include {
-  /*@dependent@*/ /*@observer@*/ cstring fname;        /* The name of the directory.  */
-  int cplusplus;               /* Only look here if we're compiling C++.  */
-  int cxx_aware;               /* Includes in this directory don't need to
-                                  be wrapped in extern "C" when compiling
-                                  C++.  */
-} include_defaults_array[]
-= {
-  /* This is the dir for fixincludes.  Put it just before
-     the files that we fix.  */
-  { GCC_INCLUDE_DIR, 0, 0 },
-  { GCC_INCLUDE_DIR2, 0, 0 },
-  { cstring_undefined, 0, 0 }
-};
-
-/*@noaccess cstring@*/
-
-/* Here is the actual list of #-directives, most-often-used first.
-   The initialize_builtins function assumes #define is the very first.  */
-
-/*@access cstring@*/
-
-static struct directive directive_table[] = {
-  {  6, do_define, "define", T_DEFINE, FALSE, TRUE, FALSE },
-  {  5, do_xifdef, "ifdef", T_IFDEF, TRUE, FALSE, FALSE },
-  {  6, do_xifdef, "ifndef", T_IFNDEF, TRUE, FALSE, FALSE },
-  {  7, do_include, "include", T_INCLUDE, TRUE, FALSE, FALSE },
-  {  5, do_endif, "endif", T_ENDIF, TRUE, FALSE, FALSE },
-  {  4, do_else, "else", T_ELSE, TRUE, FALSE, FALSE },
-  {  2, do_if, "if", T_IF, TRUE, FALSE, FALSE },
-  {  4, do_elif, "elif", T_ELIF, TRUE, FALSE, FALSE },
-  {  5, do_undef, "undef", T_UNDEF, FALSE, FALSE, FALSE },
-  {  5, do_error, "error", T_ERROR, FALSE, FALSE, FALSE },
-  {  7, do_warning, "warning", T_WARNING, FALSE, FALSE, FALSE },
-  {  6, do_pragma, "pragma", T_PRAGMA, FALSE, FALSE, TRUE},
-  {  4, do_line, "line", T_LINE, TRUE, FALSE, FALSE },
-  {  5, do_ident, "ident", T_IDENT, TRUE, FALSE, TRUE },
-  /* {  8, do_unassert, "unassert", T_UNASSERT, TRUE, FALSE, FALSE }, */
-  {  -1, 0, "", T_UNUSED, FALSE, FALSE, FALSE },
-};
-/*@noaccess cstring@*/
-
-static cstring searchPath_unparse (struct file_name_list *search_start) 
-{
-  cstring res = cstring_newEmpty ();
-  struct file_name_list *searchptr = NULL;
-
-  for (searchptr = search_start; searchptr != NULL;
-       searchptr = searchptr->next)
-    {
-      if (!cstring_isEmpty (searchptr->fname)) {
-       res = cstring_concatFree1 (res, searchptr->fname);
-       if (searchptr->next != NULL) {
-         res = cstring_appendChar (res, ';');
-       }
-      }
-    }
-
-  return res;
-}
-
-/*@+charint@*/
-static void
-initialize_char_syntax (struct cppOptions *opts)
-{
-  char i;
-
-  /*
-   * Set up is_idchar and is_idstart tables.  These should be
-   * faster than saying (is_alpha (c) || c == '_'), etc.
-   * Set up these things before calling any routines tthat
-   * refer to them.
-   */
-
-  for (i = 'a'; i <= 'z'; i++) {
-    is_idchar[i - 'a' + 'A'] = TRUE;
-    is_idchar[(int) i] = TRUE;
-    is_idstart[i - 'a' + 'A'] = TRUE;
-    is_idstart[(int) i] = TRUE;
-  }
-
-  for (i = '0'; i <= '9'; i++)
-    {
-      is_idchar[(int) i] = TRUE;
-    }
-
-  is_idchar['_'] = TRUE;
-  is_idstart['_'] = TRUE;
-  is_idchar['$'] = opts->dollars_in_ident;
-  is_idstart['$'] = opts->dollars_in_ident;
-
-  /* horizontal space table */
-  is_hor_space[' '] = TRUE;
-  is_hor_space['\t'] = TRUE;
-  is_hor_space['\v'] = TRUE;
-  is_hor_space['\f'] = TRUE;
-  is_hor_space['\r'] = TRUE;
-
-  is_space[' '] = TRUE;
-  is_space['\t'] = TRUE;
-  is_space['\v'] = TRUE;
-  is_space['\f'] = TRUE;
-  is_space['\n'] = TRUE;
-  is_space['\r'] = TRUE;
-}
-
-bool isIdentifierChar (char c)
-{
-  return is_idchar[(int) c];
-}
-
-/* Place into P_PFILE a quoted string representing the string SRC.
-   Caller must reserve enough space in pfile->token_buffer.  */
-
-static void
-quote_string (cppReader *pfile, char *src)
-{
-  char c;
-
-  cppReader_putCharQ (pfile, '\"');
-  for (;;)
-    {
-      switch ((c = *src++))
-       {
-       default:
-         if (isprint (c))
-           cppReader_putCharQ (pfile, c);
-         else
-           {
-             sprintf (cppReader_getPWritten (pfile), "\\%03o",
-                      (unsigned int) c);
-             cppReader_adjustWritten (pfile, (size_t) 4);
-           }
-         /*@switchbreak@*/ break;
-
-       case '\"':
-       case '\\':
-         cppReader_putCharQ (pfile, '\\');
-         cppReader_putCharQ (pfile, c);
-         /*@switchbreak@*/ break;
-
-       case '\0':
-         cppReader_putCharQ (pfile, '\"');
-         cppReader_nullTerminateQ (pfile);
-         return;
-       }
-    }
-}
-
-/* Re-allocates PFILE->token_buffer so it will hold at least N more chars.  */
-
-void
-cppReader_growBuffer (cppReader *pfile, size_t n)
-{
-  size_t old_written = cppReader_getWritten (pfile);
-  pfile->token_buffer_size = n + 2 * pfile->token_buffer_size;
-  pfile->token_buffer = (char *)
-    drealloc (pfile->token_buffer, pfile->token_buffer_size);
-  cppReader_setWritten (pfile, old_written);
-}
-
-/*
- * process a given definition string, for initialization
- * If STR is just an identifier, define it with value 1.
- * If STR has anything after the identifier, then it should
- * be identifier=definition.
- */
-
-void
-cppReader_define (cppReader *pfile, char *str)
-{
-  char *buf = NULL;
-  char *p = str;
-
-  DPRINTF (("Cpp reader define: %s", str));
-
-  if (!is_idstart[(int) *p])
-    {
-      DPRINTF (("ERROR 1"));
-      cppReader_error (pfile,
-                      message ("Malformed option `-D%s'",
-                               cstring_fromChars (str)));
-      
-      return;
-    }
-
-  p++;
-
-  DPRINTF (("Here 2"));
-
-  while (is_idchar[(int) *p])
-    {
-      p++;
-    }
-
-  if (*p == '(') {
-    p++;
-    while (*p != ')' && *p != '\0') {
-      p++;
-    }
-
-    if (*p == ')') {
-      p++;
-    } else {
-      cppReader_error 
-       (pfile,
-        message ("Malformed option: -D%s (no closing parenthesis)", 
-                 cstring_fromChars (str)));
-    }
-  }
-
-  DPRINTF (("Here 2"));
-
-  if (*p == '\0')
-    {
-      buf = (char *) dmalloc (size_fromInt (p - str + 4));
-      strcpy ((char *) buf, str);
-      strcat ((char *) buf, " 1");
-    }
-  else if (*p != '=')
-    {
-      DPRINTF (("ERROR 2"));
-      cppReader_error (pfile,
-                      message ("Malformed option: -D%s (expected '=', found '%c')",
-                               cstring_fromChars (str),
-                               *p));
-      return;
-    }
-  else
-    {
-      char *q;
-      /* Copy the entire option so we can modify it.  */
-      DPRINTF (("Copying..."));
-      buf = (char *) dmalloc (2 * strlen (str) + 1);
-      strncpy (buf, str, size_fromInt (p - str));
-
-      /* Change the = to a space.  */
-      buf[p - str] = ' ';
-      /* Scan for any backslash-newline and remove it.  */
-      p++;
-      q = &buf[p - str];
-
-      while (*p != '\0')
-       {
-         if (*p == '\\' && p[1] == '\n')
-           p += 2;
-         else
-           *q++ = *p++;
-       }
-
-      DPRINTF (("Here we are..."));
-      *q = '\0';
-    }
-
-  llassert (buf != NULL);
-  DPRINTF (("Do define: %s / %ld", buf, size_toLong (strlen (buf))));
-  (void) do_define (pfile, NULL, buf, buf + strlen (buf));
-  sfree (buf);
-}
-
-/* Append a chain of `struct file_name_list's
-   to the end of the main include chain.
-   FIRST is gthe beginning of the chain to append, and LAST is the end.  */
-
-void
-cppReader_appendIncludeChain (cppReader *pfile,
-                     struct file_name_list *first,
-                     struct file_name_list *last)
-{
-  struct cppOptions *opts = CPPOPTIONS (pfile);
-  struct file_name_list *dir;
-
-  if (first == NULL || last == NULL)
-    {
-      return;
-    }
-
-  if (opts->include == 0)
-    {
-      opts->include = first;
-    }
-  else
-    {
-      llassert (opts->last_include->next == NULL);
-      opts->last_include->next = first;
-    }
-
-  if (opts->first_bracket_include == 0)
-    {
-      opts->first_bracket_include = first;
-
-      for (dir = first; ; dir = dir->next) {
-       int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
-       if (len > pfile->max_include_len)
-         pfile->max_include_len = len;
-       if (dir == last)
-         break;
-      }
-    }
-
-  llassert (last->next == NULL);
-  /* last->next = NULL; */
-  opts->last_include = last;
-}
-
-# if 0
-static /*@unused@*/ void 
-cppReader_showIncludeChain (cppReader *pfile)
-{
-  struct file_name_list *dirs = CPPOPTIONS (pfile)->include;
-
-  if (dirs != NULL)
-    {
-      while (dirs != NULL)
-       {
-         fprintf (stderr, "*%s*:", cstring_toCharsSafe (dirs->fname));
-         dirs = dirs->next;
-       }
-
-      fprintf (stderr, "\n");
-    }
-  else
-    {
-      fprintf (stderr, "No includes\n");
-    }
-}
-# endif
-
-cstring 
-cppReader_getIncludePath ()
-{
-  cppReader *pfile = &g_cppState;
-  struct file_name_list *dirs = CPPOPTIONS (pfile)->include;
-  cstring res = cstring_undefined;
-
-  if (dirs != NULL)
-    {
-      while (dirs != NULL)
-       {
-         res = message ("%q%c%s", res, PATH_SEPARATOR, dirs->fname);
-         dirs = dirs->next;
-       }
-    }
-  else
-    {
-      res = cstring_makeLiteral ("<no include path>");
-    }
-
-  return res;
-}
-
-void
-cppReader_addIncludeChain (cppReader *pfile, struct file_name_list *dir)
-{
-  struct cppOptions *opts = CPPOPTIONS (pfile);
-
-  if (dir == 0)
-    {
-      return;
-    }
-
-  if (opts->include == 0)
-    {
-      opts->include = dir;
-    }
-  else
-    {
-      llassert (opts->last_include->next == NULL);
-      opts->last_include->next = dir;
-    }
-
-  if (opts->first_bracket_include == 0)
-    {
-      int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
-      opts->first_bracket_include = dir;
-      if (len > pfile->max_include_len)
-       {
-         pfile->max_include_len = len;
-       }
-    }
-
-  dir->next = NULL;
-  opts->last_include = dir;
-  /* cppReader_showIncludeChain (pfile); */
-}
-
-/* Given a colon-separated list of file names PATH,
-   add all the names to the search path for include files.  */
-
-static void
-path_include (cppReader *pfile, char *path)
-{
-  char *p;
-
-#ifdef __CYGWIN32__
-  char *win32temp;
-
-  /* if we have a posix path list, convert to win32 path list */
-  win32temp = (char *) dmalloc /*@i4@*/
-    (cygwin32_posix_to_win32_path_list_buf_size (path));
-  cygwin32_posix_to_win32_path_list (path, win32temp);
-  path = win32temp;
-#endif
-
-  p = path;
-
-  if (*p != '\0')
-    while (1) {
-      char *q = p;
-      char *name;
-      struct file_name_list *dirtmp;
-
-      /* Find the end of this name.  */
-      while (*q != '\0' && *q != PATH_SEPARATOR)
-       {
-         q++;
-       }
-
-      if (p == q)
-       {
-         /* An empty name in the path stands for the current directory.  */
-         name = (char *) dmalloc ((size_t) 2);
-         name[0] = '.';
-         name[1] = '\0';
-       }
-      else
-       {
-         /* Otherwise use the directory that is named.  */
-         name = (char *) dmalloc (size_fromInt (q - p + 1));
-         memcpy (name, p, size_fromInt (q - p));
-         name[q - p] = '\0';
-       }
-
-      dirtmp = (struct file_name_list *) dmalloc (sizeof (*dirtmp));
-      dirtmp->next = 0;                /* New one goes on the end */
-      dirtmp->control_macro = 0;
-      dirtmp->c_system_include_path = 0;
-      dirtmp->fname = cstring_fromChars (name);
-      dirtmp->got_name_map = 0;
-      cppReader_addIncludeChain (pfile, dirtmp);
-
-      /* Advance past this name.  */
-      p = q;
-      if (*p == '\0')
-       break;
-      /* Skip the colon.  */
-      p++;
-    }
-}
-
-void
-cppOptions_init (cppOptions *opts)
-{
-  memset ((char *) opts, 0, sizeof *opts);
-  assertSet (opts);
-
-  opts->in_fname = NULL;
-  opts->out_fname = NULL;
-
-  /* Initialize is_idchar to allow $.  */
-  opts->dollars_in_ident = TRUE;
-
-  opts->no_line_commands = 0;
-  opts->no_trigraphs = TRUE;
-  opts->put_out_comments = 1;
-  opts->print_include_names = 0;
-  opts->dump_macros = DUMP_DEFINITIONS; /* DUMP_NONE; */
-  opts->no_output = 0;
-  opts->cplusplus = 0;
-
-  opts->cplusplus_comments = 1;
-  opts->verbose = 0;
-  opts->lang_asm = 0;
-  opts->for_lint = 0;
-  opts->chill = 0;
-  opts->pedantic_errors = 0;
-  opts->warn_comments = 0;
-  opts->warnings_are_errors = 0;
-
-  initialize_char_syntax (opts);
-}
-
-enum cpp_token
-cppReader_nullUnderflow (/*@unused@*/ cppReader *pfile)
-{
-  return CPP_EOF;
-}
-
-void
-cppReader_nullCleanup (/*@unused@*/ cppBuffer *pbuf,
-             /*@unused@*/ cppReader *pfile)
-{
-  ;
-}
-
-void
-cppReader_macroCleanup (cppBuffer *pbuf, /*@unused@*/ cppReader *pfile)
-{
-  hashNode macro = pbuf->hnode;
-
-  if (macro->type == T_DISABLED)
-    {
-      macro->type = T_MACRO;
-    }
-
-  if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
-    {
-      sfree (pbuf->buf);
-      pbuf->buf = NULL;
-    }
-}
-
-void
-cppReader_fileCleanup (cppBuffer *pbuf, /*@unused@*/ cppReader *pfile)
-{
-  if (pbuf->buf != NULL)
-    {
-      sfree (pbuf->buf);
-      pbuf->buf = NULL;
-    }
-}
-
-/* Assuming we have read '/'.
-   If this is the start of a comment (followed by '*' or '/'),
-   skip to the end of the comment, and return ' '.
-   Return EOF if we reached the end of file before the end of the comment.
-   If not the start of a comment, return '/'.  */
-
-static int
-skip_comment (cppReader *pfile, /*@null@*/ long *linep)
-{
-  int c = 0;
-
-  llassert (pfile->buffer != NULL);
-  llassert (pfile->buffer->cur != NULL);
-
-  while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n')
-    {
-      if (linep != NULL)
-       {
-         (*linep)++;
-       }
-
-      cppReader_forward (pfile, 2);
-    }
-
-  if (cppReader_peekC (pfile) == '*')
-    {
-      cppReader_forward (pfile, 1);
-
-      for (;;)
-       {
-         int prev_c = c;
-         c = cppReader_getC (pfile);
-
-         if (c == EOF)
-           {
-             return EOF;
-           }
-
-         while (c == (int) '\\' && cppReader_peekC (pfile) == (int) '\n')
-           {
-             if (linep != NULL )
-               {
-                 (*linep)++;
-               }
-
-             cppReader_forward (pfile, 1), c = cppReader_getC (pfile);
-           }
-
-         if (prev_c == (int) '*' && c == (int) '/')
-           {
-             return (int) ' ';
-           }
-
-         if (c == (int) '\n' && (linep != NULL))
-           {
-             (*linep)++;
-           }
-       }
-    }
-  else if (cppReader_peekC (pfile) == '/' 
-          && CPPOPTIONS (pfile)->cplusplus_comments)
-    {
-      cppReader_forward (pfile, 1);
-
-      for (;;)
-       {
-         c = cppReader_getC (pfile);
-
-         if (c == EOF)
-           {
-             /* Allow hash comment to be terminated by EOF.  */
-             return (int) ' '; 
-           }
-
-         while (c == (int) '\\' && cppReader_peekC (pfile) == '\n')
-           {
-             cppReader_forward (pfile, 1);
-             c = cppReader_getC (pfile);
-
-             if (linep != NULL)
-               {
-                 (*linep)++;
-               }
-           }
-
-         if (c == (int) '\n')
-           {
-             /* Don't consider final '\n' to be part of comment.  */
-             cppReader_forward (pfile, -1);
-             return (int) ' ';
-           }
-       }
-    }
-  else
-    {
-      return (int) '/';
-    }
-}
-
-/* Skip whitespace \-newline and comments.  Does not macro-expand.  */
-int /*@alt void@*/
-cppSkipHspace (cppReader *pfile)
-{
-  int nspaces = 0;
-
-  while (TRUE)
-    {
-      int c;
-
-      llassert (pfile->buffer != NULL);
-
-      c = cppReader_peekC (pfile);
-
-      if (c == EOF)
-       {
-         return 0; /* FIXME */
-       }
-
-      if (is_hor_space[c])
-       {
-         if ((c == '\f' || c == '\v') && cppReader_isPedantic (pfile))
-           cppReader_pedwarn (pfile,
-                        message ("%s in preprocessing directive",
-                                 c == '\f'
-                                 ? cstring_makeLiteralTemp ("formfeed")
-                                 : cstring_makeLiteralTemp ("vertical tab")));
-
-         nspaces++;
-         cppReader_forward (pfile, 1);
-       }
-      else if (c == '/')
-       {
-         cppReader_forward (pfile, 1);
-         c = skip_comment (pfile, NULL);
-
-         if (c == '/')
-           {
-             cppReader_forward (pfile, -1);
-           }
-
-         if (c == EOF || c == '/')
-           {
-             return nspaces;
-           }
-       }
-      else if (c == '\\' && cpp_peekN (pfile, 1) == '\n')
-       {
-         cppReader_forward (pfile, 2);
-       }
-      else if (c == '@' && CPPBUFFER (pfile)->has_escapes
-              && is_hor_space [cpp_peekN (pfile, 1)])
-       {
-         cppReader_forward (pfile, 2);
-       }
-      else
-       {
-         return nspaces;
-       }
-    }
-}
-
-/* Read the rest of the current line.
-   The line is appended to PFILE's output buffer.  */
-
-static void
-copy_rest_of_line (cppReader *pfile)
-{
-  struct cppOptions *opts = CPPOPTIONS (pfile);
-
-  for (;;)
-    {
-      int c;
-      int nextc;
-
-      llassert (pfile->buffer != NULL);
-
-      c = cppReader_getC (pfile);
-      switch (c)
-       {
-       case EOF:
-         goto end_directive;
-       case '\\':
-         if (cppReader_peekC (pfile) == '\n')
-           {
-             cppReader_forward (pfile, 1);
-             continue;
-           }
-
-       /*@fallthrough@*/ case '\'': case '\"':
-         goto scan_directive_token;
-
-       case '/':
-         nextc = cppReader_peekC (pfile);
-
-         /*
-         ** was (opts->cplusplus_comments && nextc == '*')
-         ** yoikes!
-         */
-
-         if (nextc == '*'
-             || (opts->cplusplus_comments && nextc == '/'))
-           {
-             goto scan_directive_token;
-           }
-         /*@switchbreak@*/ break;
-       case '\f':
-       case '\v':
-         if (cppReader_isPedantic (pfile))
-           cppReader_pedwarn (pfile,
-                        message ("%s in preprocessing directive",
-                                 c == '\f'
-                                 ? cstring_makeLiteralTemp ("formfeed")
-                                 : cstring_makeLiteralTemp ("vertical tab")));
-         /*@switchbreak@*/ break;
-
-       case '\n':
-         cppReader_forward (pfile, -1);
-         goto end_directive;
-       scan_directive_token:
-         cppReader_forward (pfile, -1);
-         (void) cppGetToken (pfile);
-         continue;
-       }
-      cppReader_putChar (pfile, c);
-    }
-end_directive: ;
-  cppReader_nullTerminate (pfile);
-}
-
-void
-cppReader_skipRestOfLine (cppReader *pfile)
-{
-  size_t old = cppReader_getWritten (pfile);
-  copy_rest_of_line (pfile);
-  cppReader_setWritten (pfile, old);
-}
-
-/* Handle a possible # directive.
-   '#' has already been read.  */
-
-int
-cppReader_handleDirective (cppReader *pfile)
-{
-  int c;
-  struct directive *kt = NULL;
-  int ident_length;
-  size_t after_ident = 0;
-  char *ident = NULL;
-  char *line_end = NULL;
-  size_t old_written = cppReader_getWritten (pfile);
-  int nspaces = cppSkipHspace (pfile);
-
-  c = cppReader_peekC (pfile);
-
-  if (c >= '0' && c <= '9')
-    {
-      /* Handle # followed by a line number.  */
-      if (cppReader_isPedantic (pfile))
-       {
-         cppReader_pedwarnLit
-           (pfile,
-            cstring_makeLiteralTemp ("`#' followed by integer"));
-       }
-
-      (void) do_line (pfile, NULL);
-      goto done_a_directive;
-    }
-
-
-  /* Now find the directive name.  */
-
-  cppReader_putChar (pfile, '#');
-
-  parse_name (pfile, cppReader_getC (pfile));
-
-  llassert (pfile->token_buffer != NULL);
-  ident = pfile->token_buffer + old_written + 1;
-
-  ident_length = cppReader_getPWritten (pfile) - ident;
-
-  if (ident_length == 0 && cppReader_peekC (pfile) == '\n')
-    {
-      /* A line of just `#' becomes blank.  */
-      return 1; 
-    }
-
-  for (kt = directive_table; ; kt++) 
-    {
-      if (kt->length <= 0)
-       {
-         return 0; /* goto not_a_directive; */
-       }
-
-      if (kt->length == ident_length
-         && (cstring_equalPrefix (kt->name, cstring_fromChars (ident))))
-       {
-         break;
-       }
-    }
-
-  if (kt->command_reads_line)
-    {
-      after_ident = 0;
-    }
-  else
-    {
-      /* Nonzero means do not delete comments within the directive.
-        #define needs this when -traditional.  */
-      bool comments = 1; /*cppReader_isTraditional (pfile) && kt->traditional_comments;  */
-      int save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
-      CPPOPTIONS (pfile)->put_out_comments = comments;
-      after_ident = cppReader_getWritten (pfile);
-      copy_rest_of_line (pfile);
-      CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
-    }
-
-
-  /* For #pragma and #define, we may want to pass through the directive.
-     Other directives may create output, but we don't want the directive
-     itself out, so we pop it now.  For example #include may write a #line
-     command (see comment in do_include), and conditionals may emit
-     #failed ... #endfailed stuff.  But note that popping the buffer
-     means the parameters to kt->func may point after pfile->limit
-     so these parameters are invalid as soon as something gets appended
-     to the token_buffer.  */
-
-  line_end = cppReader_getPWritten (pfile);
-
-
-  if (!kt->pass_thru && kt->type != T_DEFINE)
-    {
-      cppReader_setWritten (pfile, old_written);
-    }
-
-  llassert (pfile->token_buffer != NULL);
-
-  /* was kt->pass_thru || */
-
-  if (kt->type == T_DEFINE
-      && cpp_shouldCheckMacro (pfile, pfile->token_buffer + old_written))
-    {
-      char *p = pfile->token_buffer + old_written;
-
-      /*
-      ** Still need to record value for preprocessing, so 
-      ** #ifdef's, etc. using the value behave correctly.
-      */
-      
-      (void) do_defineAux (pfile, kt, 
-                          pfile->token_buffer + after_ident,
-                          line_end,
-                          TRUE);
-      
-      if (*p == '#')
-       {
-         *p = ' ';
-       }
-
-      SKIP_WHITE_SPACE (p);
-
-      llassert (*p == 'd');
-      *p++ = LLMRCODE[0];
-
-      llassert (*p == 'e');
-      *p++ = LLMRCODE[1];
-
-      llassert (*p == 'f');
-      *p++ = LLMRCODE[2];
-
-      llassert (*p == 'i');
-      *p++ = LLMRCODE[3];
-
-      llassert (*p == 'n');
-      *p++ = LLMRCODE[4];
-
-      llassert (*p == 'e');
-
-      /*
-      ** This is way-bogus.  We use the last char to record the number of
-      ** spaces.  Its too hard to get them back into the input stream.
-      */
-
-      if (nspaces > 9) nspaces = 9;
-
-      *p++ = '0' + nspaces;
-
-      return 0; /* not_a_directive */
-    }
-  else if (kt->pass_thru)
-    {
-      /* Just leave the entire #define in the output stack.  */
-      return 0; /* not_a_directive */
-
-    }
-  else if (kt->type == T_DEFINE
-          && CPPOPTIONS (pfile)->dump_macros == DUMP_NAMES)
-    {
-      char *p = pfile->token_buffer + old_written + 7;  /* Skip "#define". */
-      SKIP_WHITE_SPACE (p);
-
-      while (is_idchar[(int) *p])
-       {
-         p++;
-       }
-
-      pfile->limit = p;
-      cppReader_putChar (pfile, '\n');
-    }
-  else if (kt->type == T_DEFINE)
-    {
-      cppReader_setWritten (pfile, old_written);
-    }
-  else
-    {
-      ;
-    }
-
-done_a_directive:
-  if (kt == NULL) {
-    return 1;
-  } else {
-    llassert (kt->func != NULL);
-    (void) (kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end);
-    return 1;
-  }
-}
-
-/* Pass a directive through to the output file.
-   BUF points to the contents of the directive, as a contiguous string.
-   LIMIT points to the first character past the end of the directive.
-   KEYWORD is the keyword-table entry for the directive.  */
-
-static void
-pass_thru_directive (char *buf, char *limit,
-                    cppReader *pfile,
-                    struct directive *keyword)
-{
-  int keyword_length = keyword->length;
-
-  cppReader_reserve (pfile,
-                    size_fromInt (2 + keyword_length + (limit - buf)));
-  cppReader_putCharQ (pfile, '#');
-  /*@-observertrans@*/
-  cppReader_putStrN (pfile, cstring_toCharsSafe (keyword->name),
-                    size_fromInt (keyword_length));
-  /*:=observertrans@*/
-
-  if (limit != buf && buf[0] != ' ')
-    {
-      /* Was a bug, since reserve only used 1 + ... */
-      cppReader_putCharQ (pfile, ' ');
-    }
-
-  cppReader_putStrN (pfile, buf, size_fromInt (limit - buf));
-}
-
-/* Read a replacement list for a macro with parameters.
-   Build the DEFINITION structure.
-   Reads characters of text starting at BUF until END.
-   ARGLIST specifies the formal parameters to look for
-   in the text of the definition; NARGS is the number of args
-   in that list, or -1 for a macro name that wants no argument list.
-   MACRONAME is the macro name itself (so we can avoid recursive expansion)
-   and NAMELEN is its length in characters.
-
-   Note that comments, backslash-newlines, and leading white space
-   have already been deleted from the argument.  */
-
-static DEFINITION *
-collect_expansion (cppReader *pfile, char *buf, char *limit,
-                  int nargs, /*@null@*/ struct arglist *arglist)
-{
-  DEFINITION *defn;
-  char *p, *lastp, *exp_p;
-  struct reflist *endpat = NULL;
-  /* Pointer to first nonspace after last ## seen.  */
-  char *concat = 0;
-  /* Pointer to first nonspace after last single-# seen.  */
-  char *stringify = 0;
-  size_t maxsize;
-  char expected_delimiter = '\0';
-
-
-  /* Scan thru the replacement list, ignoring comments and quoted
-     strings, picking up on the macro calls.  It does a linear search
-     thru the arg list on every potential symbol.  Profiling might say
-     that something smarter should happen.  */
-
-  if (limit < buf)
-    abort ();
-
-  /* Find the beginning of the trailing whitespace.  */
-  p = buf;
-
-  while (p < limit && is_space[(int) limit[-1]])
-    {
-      limit--;
-    }
-
-  /* Allocate space for the text in the macro definition.
-     Leading and trailing whitespace chars need 2 bytes each.
-     Each other input char may or may not need 1 byte,
-     so this is an upper bound.  The extra 5 are for invented
-     leading and trailing newline-marker and final null.  */
-  maxsize = (sizeof (*defn) + (limit - p) + 5);
-
-  /* Occurrences of '@' get doubled, so allocate extra space for them.  */
-  while (p < limit)
-    {
-      if (*p++ == '@')
-       {
-         maxsize++;
-       }
-    }
-
-  defn = (DEFINITION *) dmalloc (maxsize);
-  defn->noExpand = FALSE;
-  defn->file = NULL;
-  defn->pattern = NULL;
-  defn->nargs = nargs;
-  defn->predefined = NULL;
-
-  exp_p = defn->expansion = (char *) defn + sizeof (*defn);
-
-  defn->line = 0;
-  defn->rest_args = NULL;
-  defn->args.argnames = NULL;
-
-  lastp = exp_p;
-
-  p = buf;
-
-  /* Add one initial space escape-marker to prevent accidental
-     token-pasting (often removed by macroexpand).  */
-  *exp_p++ = '@';
-  *exp_p++ = ' ';
-
-  if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
-    cppReader_errorLit (pfile,
-                       cstring_makeLiteralTemp ("`##' at start of macro definition"));
-    p += 2;
-  }
-
-  /* Process the main body of the definition.  */
-  while (p < limit) {
-    int skipped_arg = 0;
-    register char c = *p++;
-
-    *exp_p++ = c;
-
-    if (!cppReader_isTraditional (pfile)) {
-      switch (c) {
-      case '\'':
-      case '\"':
-       if (expected_delimiter != '\0')
-         {
-           if (c == expected_delimiter)
-             expected_delimiter = '\0';
-         }
-       else
-         {
-           expected_delimiter = c;
-         }
-       /*@switchbreak@*/ break;
-
-      case '\\':
-       if (p < limit && (expected_delimiter != '\0'))
-         {
-           /* In a string, backslash goes through
-              and makes next char ordinary.  */
-           *exp_p++ = *p++;
-         }
-       /*@switchbreak@*/ break;
-
-      case '@':
-       /* An '@' in a string or character constant stands for itself,
-          and does not need to be escaped.  */
-       if (expected_delimiter == '\0')
-         {
-           *exp_p++ = c;
-         }
-
-       /*@switchbreak@*/ break;
-
-      case '#':
-       /* # is ordinary inside a string.  */
-       if (expected_delimiter != '\0')
-         {
-           /*@switchbreak@*/ break;
-         }
-
-       if (p < limit && *p == '#') {
-         /* ##: concatenate preceding and following tokens.  */
-         /* Take out the first #, discard preceding whitespace.  */
-         exp_p--;
-
-         /*@-usedef@*/
-         while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])
-           {
-             --exp_p;
-           }
-         /*@=usedef@*/
-
-         /* Skip the second #.  */
-         p++;
-         /* Discard following whitespace.  */
-         SKIP_WHITE_SPACE (p);
-         concat = p;
-         if (p == limit)
-           {
-             cppReader_errorLit (pfile,
-                           cstring_makeLiteralTemp ("`##' at end of macro definition"));
-           }
-       } else if (nargs >= 0) {
-         /* Single #: stringify following argument ref.
-            Don't leave the # in the expansion.  */
-         exp_p--;
-         SKIP_WHITE_SPACE (p);
-         if (p == limit || ! is_idstart[(int) *p]
-             || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '"')))
-           cppReader_errorLit (pfile,
-                         cstring_makeLiteralTemp ("`#' operator is not followed by a macro argument name"));
-         else
-           stringify = p;
-       } else {
-         ; /* BADBRANCH; */
-       }
-
-       /*@switchbreak@*/ break;
-      }
-    } else {
-      /* In -traditional mode, recognize arguments inside strings and
-        and character constants, and ignore special properties of #.
-        Arguments inside strings are considered "stringified", but no
-        extra quote marks are supplied.  */
-      switch (c) {
-      case '\'':
-      case '\"':
-       if (expected_delimiter != '\0') {
-         if (c == expected_delimiter)
-           expected_delimiter = '\0';
-       } else
-         expected_delimiter = c;
-       /*@switchbreak@*/ break;
-
-      case '\\':
-       /* Backslash quotes delimiters and itself, but not macro args.  */
-       if (expected_delimiter != '\0' && p < limit
-           && (*p == expected_delimiter || *p == '\\')) {
-         *exp_p++ = *p++;
-         continue;
-       }
-       /*@switchbreak@*/ break;
-
-      case '/':
-       if (expected_delimiter != '\0') /* No comments inside strings.  */
-         /*@switchbreak@*/ break;
-       if (*p == '*') {
-         /* If we find a comment that wasn't removed by cppReader_handleDirective,
-            this must be -traditional.  So replace the comment with
-            nothing at all.  */
-         exp_p--;
-         p += 1;
-         while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
-           {
-             p++;
-           }
-       }
-       /*@switchbreak@*/ break;
-      }
-    }
-
-    /* Handle the start of a symbol.  */
-    if (is_idchar[(int) c] && nargs > 0) {
-      char *id_beg = p - 1;
-      int id_len;
-
-      --exp_p;
-      while (p != limit && is_idchar[(int) *p])
-       {
-         p++;
-       }
-
-      id_len = p - id_beg;
-
-      if (is_idstart[(int) c]
-         && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {
-       register struct arglist *arg;
-
-       for (arg = arglist; arg != NULL; arg = arg->next) {
-         struct reflist *tpat;
-
-         if (arg->name[0] == c
-             && arg->length == id_len
-             && strncmp (arg->name, id_beg, size_fromInt (id_len)) == 0) {
-           char *p1;
-
-           if (expected_delimiter && CPPOPTIONS (pfile)->warn_stringify) {
-             if (cppReader_isTraditional (pfile)) {
-               cppReader_warning (pfile,
-                                  message ("macro argument `%x' is stringified.",
-                                           cstring_prefix (cstring_fromChars (arg->name), id_len)));
-             } else {
-               cppReader_warning (pfile,
-                                  message ("macro arg `%x' would be stringified with -traditional.",
-                                           cstring_prefix (cstring_fromChars (arg->name), id_len)));
-             }
-           }
-           /* If ANSI, don't actually substitute inside a string.  */
-           if (!cppReader_isTraditional (pfile) && expected_delimiter)
-             /*@innerbreak@*/ break;
-           /* make a pat node for this arg and append it to the end of
-              the pat list */
-           tpat = (struct reflist *) dmalloc (sizeof (*tpat));
-           tpat->next = NULL;
-           tpat->raw_before = (concat == id_beg);
-           tpat->raw_after = 0;
-           tpat->rest_args = arg->rest_args;
-           tpat->stringify = (cppReader_isTraditional (pfile)
-                              ? expected_delimiter != '\0'
-                              : stringify == id_beg);
-
-           if (endpat == NULL)
-             {
-               defn->pattern = tpat;
-             }
-           else
-             {
-               endpat->next = tpat;
-               /*@-branchstate@*/
-             } /*@=branchstate@*/ /* evs 2000 was =branchstate */
-
-           endpat = tpat;
-
-           tpat->argno = arg->argno;
-           tpat->nchars = exp_p - lastp;
-
-           p1 = p;
-
-           SKIP_WHITE_SPACE (p1);
-
-           if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
-             {
-               tpat->raw_after = 1;
-             }
-
-           lastp = exp_p;      /* place to start copying from next time */
-           skipped_arg = 1;
-
-           /*@innerbreak@*/ break;
-         }
-       }
-      }
-
-      /* If this was not a macro arg, copy it into the expansion.  */
-      if (skipped_arg == 0) {
-       register char *lim1 = p;
-       p = id_beg;
-
-       while (p != lim1)
-         {
-           *exp_p++ = *p++;
-         }
-
-       if (stringify == id_beg)
-         cppReader_errorLit (pfile,
-                             cstring_makeLiteralTemp ("`#' operator should be followed by a macro argument name"));
-      }
-    }
-  }
-
-  if (!cppReader_isTraditional (pfile) && expected_delimiter == '\0')
-    {
-      /* If ANSI, put in a "@ " marker to prevent token pasting.
-        But not if "inside a string" (which in ANSI mode
-        happens only for -D option).  */
-      *exp_p++ = '@';
-      *exp_p++ = ' ';
-    }
-
-  *exp_p = '\0';
-
-  defn->length = size_fromInt (exp_p - defn->expansion);
-
-  /* Crash now if we overrun the allocated size.  */
-  if (defn->length + 1 > maxsize)
-    {
-      llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
-    }
-
-  return defn;
-}
-
-/*
- * special extension string that can be added to the last macro argument to
- * allow it to absorb the "rest" of the arguments when expanded.  Ex:
- *             #define wow(a, b...)            process (b, a, b)
- *             { wow (1, 2, 3); }      ->      { process (2, 3, 1, 2, 3); }
- *             { wow (one, two); }     ->      { process (two, one, two); }
- * if this "rest_arg" is used with the concat token '##' and if it is not
- * supplied then the token attached to with ## will not be outputted.  Ex:
- *             #define wow (a, b...)           process (b ## , a, ## b)
- *             { wow (1, 2); }         ->      { process (2, 1, 2); }
- *             { wow (one); }          ->      { process (one); {
- */
-
-/*@-readonlytrans@*/
-static char rest_extension[] = "...";
-/*:=readonlytrans@*/
-
-/*@notfunction@*/
-#define REST_EXTENSION_LENGTH  (sizeof (rest_extension) - 1)
-
-/* Create a DEFINITION node from a #define directive.  Arguments are
-   as for do_define.  */
-
-static /*@null@*/ MACRODEF
-create_definition (char *buf, char *limit,
-                  cppReader *pfile, bool predefinition,
-                  bool noExpand)
-{
-  char *bp;                    /* temp ptr into input buffer */
-  char *symname;               /* remember where symbol name starts */
-  int sym_length;              /* and how long it is */
-  int rest_args = 0;   /* really int! */
-  int line;
-  int col;
-  cstring file = (CPPBUFFER (pfile) != NULL)
-    ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp ("");
-  DEFINITION *defn;
-  int arglengths = 0;          /* Accumulate lengths of arg names
-                                  plus number of args.  */
-  MACRODEF mdef;
-
-  cppBuffer_lineAndColumn (CPPBUFFER (pfile), &line, &col);
-
-  bp = buf;
-
-  while (is_hor_space[(int) *bp])
-    {
-      bp++;
-    }
-
-  symname = bp;                        /* remember where it starts */
-
-  sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro"));
-
-  bp += sym_length;
-
-  /* Lossage will occur if identifiers or control keywords are broken
-     across lines using backslash.  This is not the right place to take
-     care of that.  */
-
-  if (*bp == '(') {
-    struct arglist *arg_ptrs = NULL;
-    int argno = 0;
-
-    bp++;                      /* skip '(' */
-    SKIP_WHITE_SPACE (bp);
-
-    /* Loop over macro argument names.  */
-    while (*bp != ')')
-      {
-       struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
-       temp->name = bp;
-       temp->next = arg_ptrs;
-       temp->argno = argno++;
-       temp->rest_args = 0;
-
-       arg_ptrs = temp;
-
-       if (rest_args != 0)
-         {
-           cppReader_pedwarn (pfile,
-                        message ("another parameter follows `%s'",
-                                 cstring_fromChars (rest_extension)));
-         }
-
-       if (!is_idstart[(int) *bp])
-         {
-           cppReader_pedwarnLit (pfile,
-                           cstring_makeLiteralTemp ("invalid character in macro parameter name"));
-         }
-
-       /* Find the end of the arg name.  */
-       while (is_idchar[(int) *bp])
-         {
-           bp++;
-           /* do we have a "special" rest-args extension here? */
-           if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
-               && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
-             {
-               rest_args = 1;
-               temp->rest_args = 1;
-               /*@innerbreak@*/ break;
-             }
-         }
-
-       temp->length = bp - temp->name;
-
-       if (rest_args != 0)
-         {
-           bp += REST_EXTENSION_LENGTH;
-         }
-
-       arglengths += temp->length + 2;
-       SKIP_WHITE_SPACE (bp);
-
-       if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
-         cppReader_errorLit (pfile,
-                       cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));
-         goto nope;
-       }
-
-       if (*bp == ',') {
-         bp++;
-         SKIP_WHITE_SPACE (bp);
-       }
-       if (bp >= limit) {
-         cppReader_errorLit (pfile,
-                       cstring_makeLiteralTemp ("unterminated parameter list in `#define'"));
-         goto nope;
-       }
-       {
-         struct arglist *otemp;
-
-         for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
-           {
-             if (temp->length == otemp->length &&
-                 strncmp (temp->name, otemp->name, size_fromInt (temp->length)) == 0) {
-               cstring name = cstring_copyLength (temp->name, temp->length);
-               cppReader_error (pfile,
-                          message ("duplicate argument name `%x' in `#define'", name));
-               goto nope;
-             }
-           }
-       }
-      }
-
-    ++bp;                      /* skip paren */
-    SKIP_WHITE_SPACE (bp);
-    /* now everything from bp before limit is the definition.  */
-    defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
-    defn->rest_args = rest_args;
-    
-    /* Now set defn->args.argnames to the result of concatenating
-       the argument names in reverse order
-       with comma-space between them.  */
-    defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));
-
-    {
-      struct arglist *temp;
-      int i = 0;
-      for (temp = arg_ptrs; temp != NULL; temp = temp->next) {
-       memcpy (&defn->args.argnames[i], temp->name, size_fromInt (temp->length));
-       i += temp->length;
-       if (temp->next != 0) {
-         defn->args.argnames[i++] = ',';
-         defn->args.argnames[i++] = ' ';
-       }
-      }
-
-      defn->args.argnames[i] = '\0';
-    }
-
-    sfree (arg_ptrs);
-  } else {
-    /* Simple expansion or empty definition.  */
-
-    if (bp < limit)
-      {
-       if (is_hor_space[(int) *bp]) {
-         bp++;
-         SKIP_WHITE_SPACE (bp);
-       } else {
-         switch (*bp) {
-         case '!':  case '"':  case '#':  case '%':  case '&':  case '\'':
-         case ')':  case '*':  case '+':  case ',':  case '-':  case '.':
-         case '/':  case ':':  case ';':  case '<':  case '=':  case '>':
-         case '?':  case '[':  case '\\': case ']':  case '^':  case '{':
-         case '|':  case '}':  case '~':
-           cppReader_warning (pfile,
-                        message ("Missing white space after #define %x",
-                                 cstring_prefix (cstring_fromChars (symname),
-                                                 sym_length)));
-           break;
-
-         default:
-           cppReader_pedwarn (pfile,
-                        message ("Missing white space after #define %x",
-                                 cstring_prefix (cstring_fromChars (symname),
-                                                 sym_length)));
-           break;
-         }
-       }
-      }
-    /* now everything from bp before limit is the definition.  */
-    defn = collect_expansion (pfile, bp, limit, -1, NULL);
-    defn->args.argnames = mstring_createEmpty ();
-  }
-
-  defn->noExpand = noExpand;
-  DPRINTF (("No expand: %d", noExpand));
-
-  defn->line = line;
-
-  /* not: llassert (cstring_isUndefined (defn->file)); */
-  defn->file = file;
-
-  /* OP is null if this is a predefinition */
-  defn->predefined = predefinition;
-  mdef.defn = defn;
-  mdef.symnam = symname;
-  mdef.symlen = sym_length;
-
-  return mdef;
-
-nope:
-  mdef.defn = NULL;
-  mdef.symnam = NULL;
-  return mdef;
-}
-
-/* Check a purported macro name SYMNAME, and yield its length.
-   USAGE is the kind of name this is intended for.  */
-
-int cppReader_checkMacroName (cppReader *pfile,
-                     char *symname,
-                     cstring usage)
-{
-  char *p;
-  size_t sym_length;
-
-  for (p = symname; is_idchar[(int) *p]; p++)
-    {
-      ;
-    }
-
-  sym_length = size_fromInt (p - symname);
-
-  if (sym_length == 0
-      || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
-    cppReader_error (pfile, message ("invalid %s name", usage));
-  else if (!is_idstart[(int) *symname])
-    {
-      char *msg = (char *) dmalloc (sym_length + 1);
-      memcpy (msg, symname, sym_length);
-      msg[sym_length] = '\0';
-      cppReader_error (pfile, message ("invalid %s name `%s'", usage,
-                                      cstring_fromChars (msg)));
-      sfree (msg);
-    }
-  else
-    {
-      if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7)
-       {
-         cppReader_error (pfile, message ("invalid %s name `defined'", usage));
-       }
-    }
-
-  return size_toInt (sym_length);
-}
-
-/* Return zero if two DEFINITIONs are isomorphic.  */
-
-static bool
-compare_defs (DEFINITION *d1, DEFINITION *d2)
-{
-  register struct reflist *a1, *a2;
-  register char *p1 = d1->expansion;
-  register char *p2 = d2->expansion;
-  bool first = TRUE;
-
-  if (d1->nargs != d2->nargs)
-    {
-      return TRUE;
-    }
-
-  llassert (d1->args.argnames != NULL);
-  llassert (d2->args.argnames != NULL);
-
-  if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames) != 0)
-    {
-      return TRUE;
-    }
-
-  for (a1 = d1->pattern, a2 = d2->pattern;
-       (a1 != NULL) && (a2 != NULL);
-       a1 = a1->next, a2 = a2->next) {
-    if (!((a1->nchars == a2->nchars
-          && (strncmp (p1, p2, size_fromInt (a1->nchars)) == 0))
-         || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
-       || a1->argno != a2->argno
-       || a1->stringify != a2->stringify
-       || a1->raw_before != a2->raw_before
-       || a1->raw_after != a2->raw_after)
-      return TRUE;
-    first = 0;
-    p1 += a1->nchars;
-    p2 += a2->nchars;
-  }
-  if (a1 != a2)
-    return TRUE;
-
-  if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
-                    p2, d2->length - (p2 - d2->expansion), 1))
-    return TRUE;
-
-  return FALSE;
-}
-
-/* Return TRUE if two parts of two macro definitions are effectively different.
-   One of the parts starts at BEG1 and has LEN1 chars;
-   the other has LEN2 chars at BEG2.
-   Any sequence of whitespace matches any other sequence of whitespace.
-   FIRST means these parts are the first of a macro definition;
-   so ignore leading whitespace entirely.
-   LAST means these parts are the last of a macro definition;
-   so ignore trailing whitespace entirely.  */
-
-static bool
-comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last)
-{
-  char *end1 = beg1 + len1;
-  char *end2 = beg2 + len2;
-
-  if (first) {
-    while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }
-    while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }
-  }
-  if (last) {
-    while (beg1 != end1 && is_space[(int) end1[-1]]) { end1--; }
-    while (beg2 != end2 && is_space[(int) end2[-1]]) { end2--; }
-  }
-  while (beg1 != end1 && beg2 != end2) {
-    if (is_space[(int) *beg1] && is_space[(int) *beg2]) {
-      while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }
-      while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }
-    } else if (*beg1 == *beg2) {
-      beg1++; beg2++;
-    } else break;
-  }
-  return (beg1 != end1) || (beg2 != end2);
-}
-
-/* Process a #define command.
-   BUF points to the contents of the #define command, as a contiguous string.
-   LIMIT points to the first character past the end of the definition.
-   KEYWORD is the keyword-table entry for #define,
-   or NULL for a "predefined" macro.  */
-
-static int
-do_defineAux (cppReader *pfile, struct directive *keyword,
-             char *buf, char *limit, bool noExpand)
-{
-  int hashcode;
-  MACRODEF mdef;
-  hashNode hp;
-  
-  DPRINTF (("Define aux: %d", noExpand));
-
-  mdef = create_definition (buf, limit, pfile, keyword == NULL, noExpand);
-
-  if (mdef.defn == 0)
-    goto nope;
-
-  hashcode = hashf (mdef.symnam, mdef.symlen, CPP_HASHSIZE);
-
-  DPRINTF (("Macro: %s / %s", 
-           cstring_copyLength (mdef.symnam, mdef.symlen),
-           bool_unparse (noExpand)));
-
-  if ((hp = cppReader_lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL)
-    {
-      bool ok = FALSE;
-
-      /* Redefining a precompiled key is ok.  */
-      if (hp->type == T_PCSTRING)
-       ok = TRUE;
-      /* Redefining a macro is ok if the definitions are the same.  */
-      else if (hp->type == T_MACRO)
-       ok = !compare_defs (mdef.defn, hp->value.defn);
-      /* Redefining a constant is ok with -D.  */
-      else if (hp->type == T_CONST)
-       ok = !CPPOPTIONS (pfile)->done_initializing;
-      else {
-       BADBRANCH;
-      }
-
-      /* Print the warning if it's not ok.  */
-      if (!ok)
-       {
-         /*
-         ** If we are passing through #define and #undef directives, do
-         ** that for this re-definition now.
-         */
-
-         if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
-           {
-             /* llassert (keyword != NULL); */
-             pass_thru_directive (buf, limit, pfile, keyword);
-           }
-
-         cpp_setLocation (pfile);
-
-         if (hp->type == T_MACRO)
-           {
-             if (hp->value.defn->noExpand)
-               {
-                 ; /* error will be reported checking macros */
-               }
-             else
-               {
-                 genppllerrorhint
-                   (FLG_MACROREDEF,
-                    message ("Macro %q already defined",
-                             cstring_copyLength (mdef.symnam, mdef.symlen)),
-                    message ("%q: Previous definition of %q",
-                             fileloc_unparseRaw (hp->value.defn->file,
-                                                (int) hp->value.defn->line),
-                             cstring_copyLength (mdef.symnam, mdef.symlen)));
-               }
-           }
-         else
-           {
-             genppllerror (FLG_MACROREDEF,
-                           message ("Macro %q already defined",
-                                    cstring_copyLength (mdef.symnam,
-                                                        mdef.symlen)));
-
-           }
-       }
-
-      /* Replace the old definition.  */
-      hp->type = T_MACRO;
-      hp->value.defn = mdef.defn;
-    }
-  else
-    {
-      /*
-      ** If we are passing through #define and #undef directives, do
-      ** that for this new definition now.
-      */
-
-      hashNode hn;
-
-      if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
-       {
-         pass_thru_directive (buf, limit, pfile, keyword);
-       }
-
-      DPRINTF (("Define macro: %s / %d", 
-               mdef.symnam, mdef.defn->noExpand));
-      
-      hn = cppReader_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);
-      /*@-branchstate@*/
-    } /*@=branchstate@*/
-
-  return 0;
-
-nope:
-
-  return 1;
-}
-
-static int
-do_define (cppReader *pfile, struct directive *keyword,
-          char *buf, char *limit)
-{
-  DPRINTF (("Regular do define"));
-  return do_defineAux (pfile, keyword, buf, limit, FALSE);
-}
-
-/* This structure represents one parsed argument in a macro call.
-   `raw' points to the argument text as written (`raw_length' is its length).
-   `expanded' points to the argument's macro-expansion
-   (its length is `expand_length').
-   `stringified_length' is the length the argument would have
-   if stringified.
-   `use_count' is the number of times this macro arg is substituted
-   into the macro.  If the actual use count exceeds 10,
-   the value stored is 10.  */
-
-/* raw and expanded are relative to ARG_BASE */
-/*@notfunction@*/
-#define ARG_BASE ((pfile)->token_buffer)
-
-struct argdata {
-  /* Strings relative to pfile->token_buffer */
-  long raw;
-  size_t expanded;
-  size_t stringified;
-  int raw_length;
-  int expand_length;
-  int stringified_length;
-  bool newlines;
-  int use_count;
-};
-
-/* Allocate a new cppBuffer for PFILE, and push it on the input buffer stack.
-   If BUFFER != NULL, then use the LENGTH characters in BUFFER
-   as the new input buffer.
-   Return the new buffer, or NULL on failure.  */
-
-/*@null@*/ /*@exposed@*/ cppBuffer *
-cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length)
-{
-  cppBuffer *buf = cppReader_getBuffer (pfile);
-
-  if (buf == pfile->buffer_stack)
-    {
-      cppReader_fatalError
-       (pfile,
-        message ("%s: macro or `#include' recursion too deep",
-                 (buf->fname != NULL)
-                 ? buf->fname
-                 : cstring_makeLiteral ("<no name>")));
-      sfreeEventually (buffer);
-      return NULL;
-    }
-
-  llassert (buf != NULL);
-
-  buf--;
-  memset ((char *) buf, 0, sizeof (*buf));
-  CPPBUFFER (pfile) = buf;
-
-  buf->if_stack = pfile->if_stack;
-  buf->cleanup = cppReader_nullCleanup;
-  buf->underflow = cppReader_nullUnderflow;
-  buf->buf = buffer;
-  buf->cur = buf->buf;
-
-  if (buffer != NULL)
-    {
-      buf->alimit = buf->rlimit = buffer + length;
-    }
-  else
-    {
-      buf->alimit = buf->rlimit = NULL;
-    }
-
-  return buf;
-}
-
-cppBuffer *
-cppReader_popBuffer (cppReader *pfile)
-{
-  cppBuffer *buf = CPPBUFFER (pfile);
-
-  llassert (buf != NULL);
-
-  (void) (*buf->cleanup) (buf, pfile);
-  return ++CPPBUFFER (pfile);
-}
-
-/* Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer.
-   Pop the buffer when done.  */
-
-void
-cppReader_scanBuffer (cppReader *pfile)
-{
-  cppBuffer *buffer = CPPBUFFER (pfile);
-  for (;;)
-    {
-      enum cpp_token token;
-      
-      token = cppGetToken (pfile);
-
-      if (token == CPP_EOF) /* Should not happen ...  */
-       {
-         break;
-       }
-
-      if (token == CPP_POP && CPPBUFFER (pfile) == buffer)
-       {
-         (void) cppReader_popBuffer (pfile);
-         break;
-       }
-    }
-}
-
-/*
- * Rescan a string (which may have escape marks) into pfile's buffer.
- * Place the result in pfile->token_buffer.
- *
- * The input is copied before it is scanned, so it is safe to pass
- * it something from the token_buffer that will get overwritten
- * (because it follows cppReader_getWritten).  This is used by do_include.
- */
-
-static void
-cpp_expand_to_buffer (cppReader *pfile, char *buf, size_t length)
-{
-  register cppBuffer *ip;
-  char *limit = buf + length;
-  char *buf1, *p1, *p2;
-
-  /* evans - 2001-08-26
-  ** length is unsigned - this doesn't make sense
-  if (length < 0)
-    abort ();
-  **
-  */
-
-  /* Set up the input on the input stack.  */
-
-  buf1 = (char *) dmalloc (length + 1);
-
-  p1 = buf;
-  p2 = buf1;
-
-  while (p1 != limit)
-    {
-      *p2++ = *p1++;
-    }
-
-  buf1[length] = '\0';
-
-  ip = cppReader_pushBuffer (pfile, buf1, length);
-
-  if (ip == NULL)
-    return;
-
-  ip->has_escapes = TRUE;
-
-  /* Scan the input, create the output.  */
-  cppReader_scanBuffer (pfile);
-
-  cppReader_nullTerminate (pfile);
-}
-
-static void
-adjust_position (char *buf, char *limit, int *linep, int *colp)
-{
-  while (buf < limit)
-    {
-      char ch = *buf++;
-      if (ch == '\n')
-       (*linep)++, (*colp) = 1;
-      else
-       (*colp)++;
-    }
-}
-
-/* Move line_base forward, updating lineno and colno.  */
-
-static void
-update_position (cppBuffer *pbuf)
-{
-  char *old_pos;
-  char *new_pos = pbuf->cur;
-  register struct parse_marker *mark;
-
-  llassert (pbuf->buf != NULL);
-  old_pos = pbuf->buf + pbuf->line_base;
-
-  for (mark = pbuf->marks;  mark != NULL; mark = mark->next)
-    {
-      if (pbuf->buf + mark->position < new_pos)
-       new_pos = pbuf->buf + mark->position;
-    }
-  pbuf->line_base += new_pos - old_pos;
-
-  llassert (old_pos != NULL);
-  llassert (new_pos != NULL);
-
-  adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno);
-}
-
-void
-cppBuffer_lineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep,
-                        /*@null@*/ /*@out@*/ int *colp)
-{
-  int dummy;
-
-  if (colp == NULL)
-    {
-      colp = &dummy;
-      /*@-branchstate@*/
-    } /*@=branchstate@*/
-
-  if (pbuf != NULL)
-    {
-      *linep = pbuf->lineno;
-      *colp = pbuf->colno;
-
-      llassert (pbuf->buf != NULL);
-      llassert (pbuf->cur != NULL);
-
-      adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp);
-    }
-  else
-    {
-      *linep = 0;
-      *colp = 0;
-    }
-}
-
-/* Return the cppBuffer that corresponds to a file (not a macro).  */
-
-/*@exposed@*/ /*@null@*/ cppBuffer *cppReader_fileBuffer (cppReader *pfile)
-{
-  cppBuffer *ip = cppReader_getBuffer (pfile);
-
-  for ( ;
-       ip != NULL && ip != cppReader_nullBuffer (pfile); 
-       ip = cppBuffer_prevBuffer (ip))
-    {
-      if (ip->fname != NULL)
-       {
-         return ip;
-       }
-    }
-  
-  return NULL;
-}
-
-static long
-count_newlines (char *buf, char *limit)
-{
-  register long count = 0;
-
-  while (buf < limit)
-    {
-      char ch = *buf++;
-      if (ch == '\n')
-       count++;
-    }
-  return count;
-}
-
-/*
- * write out a #line command, for instance, after an #include file.
- * If CONDITIONAL is nonzero, we can omit the #line if it would
- * appear to be a no-op, and we can output a few newlines instead
- * if we want to increase the line number by a small amount.
- * FILE_CHANGE says whether we are entering a file, leaving, or neither.
- */
-
-static void
-output_line_command (cppReader *pfile, bool conditional,
-                    enum file_change_code file_change)
-{
-  int line, col;
-  cppBuffer *ip = CPPBUFFER (pfile);
-  cppBuffer *buf;
-
-  llassert (ip != NULL);
-
-  if (ip->fname == NULL)
-    return;
-
-  update_position (ip);
-
-  if (CPPOPTIONS (pfile)->no_line_commands
-      || CPPOPTIONS (pfile)->no_output)
-    return;
-
-  buf = CPPBUFFER (pfile);
-
-  llassert (buf != NULL);
-
-  line = buf->lineno;
-  col = buf->colno;
-
-  llassert (ip->cur != NULL);
-
-  adjust_position (cppLineBase (ip), ip->cur, &line, &col);
-
-  if (CPPOPTIONS (pfile)->no_line_commands)
-    return;
-
-  if (conditional) {
-    if (line == pfile->lineno)
-      return;
-
-    /* If the inherited line number is a little too small,
-       output some newlines instead of a #line command.  */
-
-    if (line > pfile->lineno && line < pfile->lineno + 8)
-      {
-       cppReader_reserve (pfile, 20);
-       while (line > pfile->lineno)
-         {
-           cppReader_putCharQ (pfile, '\n');
-           pfile->lineno++;
-         }
-
-       return;
-      }
-  }
-
-  cppReader_reserve (pfile,
-                    size_fromInt (4 * cstring_length (ip->nominal_fname) + 50));
-
-  {
-#ifdef OUTPUT_LINE_COMMANDS
-    static char sharp_line[] = "#line ";
-#else
-    static char sharp_line[] = "# ";
-#endif
-    cppReader_putStrN (pfile, sharp_line, sizeof(sharp_line)-1);
-  }
-
-  sprintf (cppReader_getPWritten (pfile), "%d ", line);
-  cppReader_adjustWritten (pfile, strlen (cppReader_getPWritten (pfile)));
-
-  quote_string (pfile, cstring_toCharsSafe (ip->nominal_fname));
-
-  if (file_change != same_file) {
-    cppReader_putCharQ (pfile, ' ');
-    cppReader_putCharQ (pfile, file_change == enter_file ? '1' : '2');
-  }
-  /* Tell cc1 if following text comes from a system header file.  */
-  if (ip->system_header_p != '\0') {
-    cppReader_putCharQ (pfile, ' ');
-    cppReader_putCharQ (pfile, '3');
-  }
-#ifndef NO_IMPLICIT_EXTERN_C
-  /* Tell cc1plus if following text should be treated as C.  */
-  if (ip->system_header_p == (char) 2 && CPPOPTIONS (pfile)->cplusplus) {
-    cppReader_putCharQ (pfile, ' ');
-    cppReader_putCharQ (pfile, '4');
-  }
-#endif
-  cppReader_putCharQ (pfile, '\n');
-  pfile->lineno = line;
-}
-
-
-/*
- * Parse a macro argument and append the info on PFILE's token_buffer.
- * REST_ARGS means to absorb the rest of the args.
- * Return nonzero to indicate a syntax error.
- */
-
-static enum cpp_token
-macarg (cppReader *pfile, int rest_args)
-{
-  int paren = 0;
-  enum cpp_token token;
-  char save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
-  bool oldexpand = pfile->no_macro_expand;
-  CPPOPTIONS (pfile)->put_out_comments = 1;
-
-  /* Try to parse as much of the argument as exists at this
-     input stack level.  */
-
-  pfile->no_macro_expand = TRUE;
-
-  for (;;)
-    {
-      token = cppGetToken (pfile);
-
-      switch (token)
-       {
-       case CPP_EOF:
-         goto done;
-       case CPP_POP:
-         /* If we've hit end of file, it's an error (reported by caller).
-            Ditto if it's the end of cpp_expand_to_buffer text.
-            If we've hit end of macro, just continue.  */
-         if (!cppBuffer_isMacro (CPPBUFFER (pfile)))
-           goto done;
-         /*@switchbreak@*/ break;
-       case CPP_LPAREN:
-         paren++;
-         /*@switchbreak@*/ break;
-       case CPP_RPAREN:
-         if (--paren < 0)
-           goto found;
-         /*@switchbreak@*/ break;
-       case CPP_COMMA:
-         /* if we've returned to lowest level and
-            we aren't absorbing all args */
-         if (paren == 0 && rest_args == 0)
-           goto found;
-         /*@switchbreak@*/ break;
-       found:
-         /* Remove ',' or ')' from argument buffer.  */
-         cppReader_adjustWritten (pfile, -1);
-         goto done;
-       default:
-         ;
-       }
-    }
-
-done:
-  CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
-  pfile->no_macro_expand = oldexpand;
-
-  return token;
-}
-
-
-/* Turn newlines to spaces in the string of length LENGTH at START,
-   except inside of string constants.
-   The string is copied into itself with its beginning staying fixed.  */
-
-static int
-change_newlines (char *start, int length)
-{
-  register char *ibp;
-  register char *obp;
-  register char *limit;
-  char c;
-
-  ibp = start;
-  limit = start + length;
-  obp = start;
-
-  while (ibp < limit) {
-    *obp++ = c = *ibp++;
-    switch (c) {
-
-    case '\'':
-    case '\"':
-      /* Notice and skip strings, so that we don't delete newlines in them.  */
-      {
-       char quotec = c;
-       while (ibp < limit) {
-         *obp++ = c = *ibp++;
-         if (c == quotec)
-           /*@innerbreak@*/ break;
-         if (c == '\n' && quotec == '\'')
-           /*@innerbreak@*/ break;
-       }
-      }
-    /*@switchbreak@*/ break;
-    }
-  }
-
-  return obp - start;
-}
-
-static /*@observer@*/ struct tm *
-timestamp (/*@returned@*/ cppReader *pfile)
-{
-  if (pfile->timebuf == NULL)
-    {
-      time_t t = time ((time_t *) 0);
-      pfile->timebuf = localtime (&t);
-    }
-
-  llassert (pfile->timebuf != NULL);
-
-  return pfile->timebuf;
-}
-
-static ob_mstring monthnames[] = {
-  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
-} ;
-
-/*
- * expand things like __FILE__.  Place the expansion into the output
- * buffer *without* rescanning.
- */
-
-static void
-special_symbol (hashNode hp, cppReader *pfile)
-{
-  cstring buf = cstring_undefined;
-  size_t len;
-  int true_indepth;
-  cppBuffer *ip;
-  struct tm *timebuf;
-
-  int paren = 0;               /* For special `defined' keyword */
-
-  for (ip = cppReader_getBuffer (pfile); ip != NULL; ip = cppBuffer_prevBuffer (ip))
-    {
-      if (ip == cppReader_nullBuffer (pfile))
-       {
-         cppReader_errorLit (pfile,
-                       cstring_makeLiteralTemp ("cccp error: not in any file?!"));
-         return;                       /* the show must go on */
-       }
-
-      if (ip != NULL && ip->fname != NULL)
-       {
-         break;
-       }
-    }
-
-  switch (hp->type)
-    {
-    case T_FILE:
-    case T_BASE_FILE:
-      {
-       char *string;
-       if (hp->type == T_BASE_FILE)
-         {
-           while (cppBuffer_prevBuffer (ip) != cppReader_nullBuffer (pfile))
-             {
-               ip = cppBuffer_prevBuffer (ip);
-             }
-         }
-
-       llassert (ip != NULL);
-       string = cstring_toCharsSafe (ip->nominal_fname);
-
-       if (string == NULL)
-         {
-           string = "";
-         }
-
-       cppReader_reserve (pfile, 3 + 4 * strlen (string));
-       quote_string (pfile, string);
-       return;
-      }
-
-    case T_INCLUDE_LEVEL:
-      true_indepth = 0;
-      ip = cppReader_getBuffer (pfile);
-
-      for (;  ip != cppReader_nullBuffer (pfile) && ip != NULL;
-          ip = cppBuffer_prevBuffer (ip))
-       {
-         if (ip != NULL && ip->fname != NULL)
-           {
-             true_indepth++;
-           }
-       }
-
-      buf = message ("%d", true_indepth - 1);
-      break;
-
-    case T_VERSION:
-      buf = message ("\"%s\"", cstring_makeLiteralTemp (CPP_VERSION));
-      break;
-
-#ifndef NO_BUILTIN_SIZE_TYPE
-    case T_SIZE_TYPE:
-      buf = cstring_makeLiteral (SIZE_TYPE);
-      break;
-#endif
-
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
-    case T_PTRDIFF_TYPE:
-      buf = cstring_makeLiteral (PTRDIFF_TYPE);
-      break;
-#endif
-
-    case T_WCHAR_TYPE:
-      buf = cstring_makeLiteral (cppReader_wcharType (pfile));
-      break;
-
-    case T_USER_LABEL_PREFIX_TYPE:
-      buf = cstring_makeLiteral (USER_LABEL_PREFIX);
-      break;
-
-    case T_REGISTER_PREFIX_TYPE:
-      buf = cstring_makeLiteral (REGISTER_PREFIX);
-      break;
-
-    case T_CONST:
-      buf = message ("%d", hp->value.ival);
-      break;
-
-    case T_SPECLINE:
-      {
-       if (ip != NULL)
-         {
-           int line = ip->lineno;
-           int col = ip->colno;
-
-           llassert (ip->cur != NULL);
-           adjust_position (cppLineBase (ip), ip->cur, &line, &col);
-
-           buf = message ("%d", (int) line);
-         }
-       else
-         {
-           BADBRANCH;
-         }
-      }
-    break;
-
-    case T_DATE:
-    case T_TIME:
-      {
-       char *sbuf = (char *) dmalloc (20);
-       timebuf = timestamp (pfile);
-       if (hp->type == T_DATE)
-         {
-           sprintf (sbuf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
-                    timebuf->tm_mday, timebuf->tm_year + 1900);
-         }
-       else
-         {
-           sprintf (sbuf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
-                    timebuf->tm_sec);
-         }
-
-       buf = cstring_fromCharsNew (sbuf);
-       sfree (sbuf);
-       break;
-      }
-
-    case T_SPEC_DEFINED:
-      buf = cstring_makeLiteral (" 0 ");     /* Assume symbol is not defined */
-      ip = cppReader_getBuffer (pfile);
-
-      llassert (ip->cur != NULL);
-      SKIP_WHITE_SPACE (ip->cur);
-
-      if (*ip->cur == '(')
-       {
-         paren++;
-         ip->cur++;                    /* Skip over the paren */
-         SKIP_WHITE_SPACE (ip->cur);
-       }
-
-      if (!is_idstart[(int) *ip->cur])
-       goto oops;
-      if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))
-       goto oops;
-
-      if ((hp = cppReader_lookup (ip->cur, -1, -1)) != 0)
-       {
-         cstring_free (buf);
-         buf = cstring_makeLiteral (" 1 ");
-       }
-
-      while (is_idchar[(int) *ip->cur])
-       {
-         ++ip->cur;
-       }
-
-      SKIP_WHITE_SPACE (ip->cur);
-
-      if (paren != 0)
-       {
-         if (*ip->cur != ')')
-           goto oops;
-         ++ip->cur;
-       }
-      break;
-
-    oops:
-
-      cppReader_errorLit (pfile,
-                   cstring_makeLiteralTemp ("`defined' without an identifier"));
-      break;
-
-    default:
-      cpp_setLocation (pfile);
-      llfatalerror (message ("Pre-processing error: invalid special hash type"));
-    }
-
-  len = size_fromInt (cstring_length (buf));
-
-  cppReader_reserve (pfile, len + 1);
-  cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len);
-  cppReader_nullTerminateQ (pfile);
-
-  cstring_free (buf);
-  return;
-}
-
-/* Write out a #define command for the special named MACRO_NAME
-   to PFILE's token_buffer.  */
-
-static void
-dump_special_to_buffer (cppReader *pfile, char *macro_name)
-{
-  static char define_directive[] = "#define ";
-  size_t macro_name_length = strlen (macro_name);
-  output_line_command (pfile, 0, same_file);
-  cppReader_reserve (pfile, sizeof(define_directive) + macro_name_length);
-  cppReader_putStrN (pfile, define_directive, sizeof(define_directive)-1);
-  cppReader_putStrN (pfile, macro_name, macro_name_length);
-  cppReader_putCharQ (pfile, ' ');
-  cpp_expand_to_buffer (pfile, macro_name, macro_name_length);
-  cppReader_putChar (pfile, '\n');
-}
-
-/* Initialize the built-in macros.  */
-
-static void
-cppReader_installBuiltin (/*@observer@*/ char *name, ctype ctyp,
-                         int len, enum node_type type,
-                         int ivalue, /*@null@*/ /*@only@*/ char *value,
-                         int hash)
-{
-  cstring sname = cstring_fromCharsNew (name);
-
-  llassert (usymtab_inGlobalScope ());
-
-  /*
-  ** Be careful here: this is done before the ctype table has
-  ** been initialized.
-  */
-
-  if (!usymtab_exists (sname))
-    {
-      uentry ue = uentry_makeConstant (sname, ctyp, fileloc_createBuiltin ());
-
-      if (ctype_equal (ctyp, ctype_string))
-       {
-         qualList ql = qualList_new ();
-         ql = qualList_add (ql, qual_createObserver ());
-         uentry_reflectQualifiers (ue, ql);
-         qualList_free (ql);
-       }
-      
-      usymtab_addGlobalEntry (ue);
-    }
-  else
-    {
-      ;
-    }
-
-  (void) cppReader_install (name, len, type, ivalue, value, hash);
-  cstring_free (sname);
-}
-
-static void
-cppReader_installBuiltinType (/*@observer@*/ char *name, ctype ctyp,
-                             int len, enum node_type type,
-                             int ivalue,
-                             /*@only@*/ /*@null@*/ char *value, int hash)
-{
-  cstring sname = cstring_fromChars (name);
-  /* evs 2000 07 10 - removed a memory leak, detected by lclint */
-
-  llassert (usymtab_inGlobalScope ());
-
-  if (!usymtab_existsTypeEither (sname))
-    {
-      uentry ue = uentry_makeDatatype (sname, ctyp,
-                                      NO, NO,
-                                      fileloc_createBuiltin ());
-      llassert (!usymtab_existsEither (sname));
-      usymtab_addGlobalEntry (ue);
-    }
-
-  (void) cppReader_install (name, len, type, ivalue, value, hash);
-}
-
-static void
-initialize_builtins (cppReader *pfile)
-{
-  cppReader_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1);
-  cppReader_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1);
-  cppReader_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1);
-  cppReader_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1);
-  cppReader_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1);
-  cppReader_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1);
-#ifndef NO_BUILTIN_SIZE_TYPE
-  cppReader_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1);
-#endif
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
-  cppReader_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1);
-#endif
-  cppReader_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1);
-  cppReader_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1);
-  cppReader_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1);
-  cppReader_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1);
-
-  /*
-  ** No, don't define __STDC__
-  **
-
-  if (!cppReader_isTraditional (pfile))
-    {
-      cppReader_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
-    }
-
-  **
-  */
-
-# ifdef WIN32
-    cppReader_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
-# endif
-
-  /*
-  ** This is supplied using a -D by the compiler driver
-  ** so that it is present only when truly compiling with GNU C.
-  */
-
-  /*  cppReader_install ("__GNUC__", -1, T_CONST, 2, 0, -1);  */
-
-  cppReader_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1);
-
-  if (CPPOPTIONS (pfile)->debug_output)
-    {
-      dump_special_to_buffer (pfile, "__BASE_FILE__");
-      dump_special_to_buffer (pfile, "__VERSION__");
-#ifndef NO_BUILTIN_SIZE_TYPE
-      dump_special_to_buffer (pfile, "__SIZE_TYPE__");
-#endif
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
-      dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");
-#endif
-      dump_special_to_buffer (pfile, "__WCHAR_TYPE__");
-      dump_special_to_buffer (pfile, "__DATE__");
-      dump_special_to_buffer (pfile, "__TIME__");
-      if (!cppReader_isTraditional (pfile))
-       dump_special_to_buffer (pfile, "__STDC__");
-    }
-}
-
-
-/* Return 1 iff a token ending in C1 followed directly by a token C2
-   could cause mis-tokenization.  */
-
-static bool
-unsafe_chars (char c1, char c2)
-{
-  switch (c1)
-    {
-    case '+': case '-':
-      if (c2 == c1 || c2 == '=')
-       return 1;
-      goto letter;
-    case '.':
-    case '0': case '1': case '2': case '3': case '4':
-    case '5': case '6': case '7': case '8': case '9':
-    case 'e': case 'E': case 'p': case 'P':
-      if (c2 == '-' || c2 == '+')
-       return 1; /* could extend a pre-processing number */
-      goto letter;
-    case 'L':
-      if (c2 == '\'' || c2 == '\"')
-       return 1;   /* Could turn into L"xxx" or L'xxx'.  */
-      goto letter;
-    letter:
-    case '_':
-    case 'a': case 'b': case 'c': case 'd':           case 'f':
-    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
-    case 'm': case 'n': case 'o':           case 'q': case 'r':
-    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
-    case 'y': case 'z':
-    case 'A': case 'B': case 'C': case 'D':           case 'F':
-    case 'G': case 'H': case 'I': case 'J': case 'K':
-    case 'M': case 'N': case 'O':           case 'Q': case 'R':
-    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
-    case 'Y': case 'Z':
-      /* We're in the middle of either a name or a pre-processing number.  */
-      return (is_idchar[(int) c2] || c2 == '.');
-    case '<': case '>': case '!': case '%': case '#': case ':':
-    case '^': case '&': case '|': case '*': case '/': case '=':
-      return (c2 == c1 || c2 == '=');
-    }
-  return 0;
-}
-
-/* Expand a macro call.
-   HP points to the symbol that is the macro being called.
-   Put the result of expansion onto the input stack
-   so that subsequent input by our caller will use it.
-
-   If macro wants arguments, caller has already verified that
-   an argument list follows; arguments come from the input stack.  */
-
-static void
-macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
-{
-  int nargs;
-  DEFINITION *defn = hp->value.defn;
-  char *xbuf;
-  char *oxbuf = NULL;
-  int start_line;
-  int start_column;
-  size_t xbuf_len;
-  size_t old_written = cppReader_getWritten (pfile);
-  int rest_args;
-  int rest_zero = 0;
-  int i;
-  struct argdata *args = NULL;
-
-  pfile->output_escapes++;
-
-  cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
-
-  nargs = defn->nargs;
-
-  if (nargs >= 0)
-    {
-      enum cpp_token token = CPP_EOF;
-
-      args = (struct argdata *) dmalloc ((nargs + 1) * sizeof (*args));
-
-      for (i = 0; i < nargs; i++)
-       {
-         args[i].expanded = 0;
-         args[i].raw = 0;
-         args[i].raw_length = 0;
-         args[i].expand_length = args[i].stringified_length = -1;
-         args[i].use_count = 0;
-       }
-
-      /*
-      ** Parse all the macro args that are supplied.  I counts them.
-      ** The first NARGS args are stored in ARGS.
-      ** The rest are discarded.  If rest_args is set then we assume
-      ** macarg absorbed the rest of the args.
-      */
-
-      i = 0;
-      rest_args = 0;
-
-      cppReader_forward (pfile, 1); /* Discard the open-parenthesis before the first arg.  */
-      do
-       {
-         if (rest_args != 0)
-           {
-             continue;
-           }
-
-         if (i < nargs || (nargs == 0 && i == 0))
-           {
-             /* if we are working on last arg which absorbs rest of args... */
-             if (i == nargs - 1 && defn->rest_args)
-               {
-                 rest_args = 1;
-               }
-
-             args[i].raw = size_toLong (cppReader_getWritten (pfile));
-             token = macarg (pfile, rest_args);
-             args[i].raw_length = cppReader_getWritten (pfile) - args[i].raw;
-             args[i].newlines = FALSE; /* FIXME */
-           }
-         else
-           {
-             token = macarg (pfile, 0);
-           }
-
-         if (token == CPP_EOF || token == CPP_POP)
-           {
-             cppReader_errorWithLine (pfile, start_line, start_column,
-                                  cstring_fromCharsNew ("unterminated macro call"));
-             sfree (args);
-             return;
-           }
-         i++;
-       } while (token == CPP_COMMA);
-
-      /* If we got one arg but it was just whitespace, call that 0 args.  */
-      if (i == 1)
-       {
-         char *bp;
-         char *lim;
-
-         assertSet (args);
-
-         bp = ARG_BASE + args[0].raw;
-         lim = bp + args[0].raw_length;
-
-         /* cpp.texi says for foo ( ) we provide one argument.
-            However, if foo wants just 0 arguments, treat this as 0.  */
-
-         if (nargs == 0)
-           {
-             while (bp != lim && is_space[(int) *bp])
-               {
-                 bp++;
-               }
-           }
-
-         if (bp == lim)
-           i = 0;
-       }
-
-      /* Don't output an error message if we have already output one for
-        a parse error above.  */
-      rest_zero = 0;
-
-      if (nargs == 0 && i > 0)
-       {
-         cppReader_error (pfile,
-                    message ("arguments given to macro `%s'", hp->name));
-       }
-      else if (i < nargs)
-       {
-         /* traditional C allows foo() if foo wants one argument.  */
-         if (nargs == 1 && i == 0 && cppReader_isTraditional (pfile))
-           {
-             ;
-           }
-         /* the rest args token is allowed to absorb 0 tokens */
-         else if (i == nargs - 1 && defn->rest_args)
-           rest_zero = 1;
-         else if (i == 0)
-           cppReader_error (pfile,
-                      message ("macro `%s' used without args", hp->name));
-         else if (i == 1)
-           cppReader_error (pfile,
-                      message ("macro `%s' used with just one arg", hp->name));
-         else
-           {
-             cppReader_error (pfile,
-                        message ("macro `%s' used with only %d args",
-                                 hp->name, i));
-           }
-       }
-      else if (i > nargs)
-       {
-         cppReader_error (pfile,
-                    message ("macro `%s' used with too many (%d) args", hp->name, i));
-       }
-      else
-       {
-         ;
-       }
-    }
-
-  /* If macro wants zero args, we parsed the arglist for checking only.
-     Read directly from the macro definition.  */
-
-  if (nargs <= 0)
-    {
-      xbuf = defn->expansion;
-      xbuf_len = defn->length;
-    }
-  else
-    {
-      char *exp = defn->expansion;
-      int offset;      /* offset in expansion,
-                                  copied a piece at a time */
-      size_t totlen;   /* total amount of exp buffer filled so far */
-
-      register struct reflist *ap, *last_ap;
-      
-      assertSet (args); /* args is defined since the nargs > 0 path was taken */
-
-      /* Macro really takes args.  Compute the expansion of this call.  */
-
-      /* Compute length in characters of the macro's expansion.
-        Also count number of times each arg is used.  */
-      xbuf_len = defn->length;
-
-      llassert (args != NULL);
-
-      for (ap = defn->pattern; ap != NULL; ap = ap->next)
-       {
-         if (ap->stringify)
-           {
-             struct argdata *arg = &args[ap->argno];
-
-             /* Stringify it it hasn't already been */
-             assertSet (arg);
-
-             if (arg->stringified_length < 0)
-               {
-                 int arglen = arg->raw_length;
-                 bool escaped = FALSE;
-                 char in_string = '\0';
-                 char c;
-
-                 /* Initially need_space is -1.  Otherwise, 1 means the
-                    previous character was a space, but we suppressed it;
-                    0 means the previous character was a non-space.  */
-                 int need_space = -1;
-
-                 i = 0;
-                 arg->stringified = cppReader_getWritten (pfile);
-                 if (!cppReader_isTraditional (pfile))
-                   cppReader_putChar (pfile, '\"'); /* insert beginning quote */
-                 for (; i < arglen; i++)
-                   {
-                     c = (ARG_BASE + arg->raw)[i];
-
-                     if (in_string == '\0')
-                       {
-                         /* Internal sequences of whitespace are replaced by
-                            one space except within an string or char token.*/
-                         if (is_space[(int) c])
-                           {
-                             if (cppReader_getWritten (pfile) > arg->stringified
-                                 && (cppReader_getPWritten (pfile))[-1] == '@')
-                               {
-                                 /* "@ " escape markers are removed */
-                                 cppReader_adjustWritten (pfile, -1);
-                                 /*@innercontinue@*/ continue;
-                               }
-                             if (need_space == 0)
-                               need_space = 1;
-                             /*@innercontinue@*/ continue;
-                           }
-                         else if (need_space > 0)
-                           cppReader_putChar (pfile, ' ');
-                         else
-                           {
-                             ;
-                           }
-
-                         need_space = 0;
-                       }
-
-                     if (escaped)
-                       escaped = 0;
-                     else
-                       {
-                         if (c == '\\')
-                           escaped = 1;
-
-                         if (in_string != '\0')
-                           {
-                             if (c == in_string)
-                               in_string = '\0';
-                           }
-                         else if (c == '\"' || c == '\'')
-                           {
-                             in_string = c;
-                           }
-                         else
-                           {
-                             ;
-                           }
-                       }
-
-                     /* Escape these chars */
-                     if (c == '\"' || (in_string != '\0' && c == '\\'))
-                       cppReader_putChar (pfile, '\\');
-                     if (isprint (c))
-                       cppReader_putChar (pfile, c);
-                     else
-                       {
-                         cppReader_reserve (pfile, 4);
-                         sprintf (cppReader_getPWritten (pfile), "\\%03o",
-                                  (unsigned int) c);
-                         cppReader_adjustWritten (pfile, 4);
-                       }
-                   }
-                 if (!cppReader_isTraditional (pfile))
-                   cppReader_putChar (pfile, '\"'); /* insert ending quote */
-                 arg->stringified_length
-                   = size_toInt (cppReader_getWritten (pfile) - arg->stringified);
-               }
-
-             xbuf_len += args[ap->argno].stringified_length;
-           }
-         else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
-           {
-             /* Add 4 for two newline-space markers to prevent
-                token concatenation.  */
-             assertSet (args); /*@i534 shouldn't need this */
-             xbuf_len += args[ap->argno].raw_length + 4;
-           }
-         else
-           {
-             /* We have an ordinary (expanded) occurrence of the arg.
-                So compute its expansion, if we have not already.  */
-
-             assertSet (args); /*@i534 shouldn't need this */
-
-             if (args[ap->argno].expand_length < 0)
-               {
-                 args[ap->argno].expanded = cppReader_getWritten (pfile);
-                 cpp_expand_to_buffer (pfile,
-                                       ARG_BASE + args[ap->argno].raw,
-                                       size_fromInt (args[ap->argno].raw_length));
-
-                 args[ap->argno].expand_length
-                   = size_toInt (cppReader_getWritten (pfile) - args[ap->argno].expanded);
-               }
-
-             /* Add 4 for two newline-space markers to prevent
-                token concatenation.  */
-             xbuf_len += args[ap->argno].expand_length + 4;
-          }
-         if (args[ap->argno].use_count < 10)
-           args[ap->argno].use_count++;
-       }
-
-      xbuf = (char *) dmalloc (xbuf_len + 1);
-      oxbuf = xbuf;
-
-      /*
-      ** Generate in XBUF the complete expansion
-      ** with arguments substituted in.
-      ** TOTLEN is the total size generated so far.
-      ** OFFSET is the index in the definition
-      ** of where we are copying from.
-      */
-
-      offset = 0;
-      totlen = 0;
-
-      for (last_ap = NULL, ap = defn->pattern; ap != NULL;
-          last_ap = ap, ap = ap->next)
-       {
-         register struct argdata *arg = &args[ap->argno];
-         size_t count_before = totlen;
-
-         /* Add chars to XBUF.  */
-         for (i = 0; i < ap->nchars; i++, offset++)
-           {
-             xbuf[totlen++] = exp[offset];
-           }
-
-         /* If followed by an empty rest arg with concatenation,
-            delete the last run of nonwhite chars.  */
-         if (rest_zero && totlen > count_before
-             && ((ap->rest_args && ap->raw_before)
-                 || (last_ap != NULL && last_ap->rest_args
-                     && last_ap->raw_after)))
-           {
-             /* Delete final whitespace.  */
-             while (totlen > count_before && is_space[(int) xbuf[totlen - 1]])
-               {
-                 totlen--;
-               }
-
-             /* Delete the nonwhites before them.  */
-             while (totlen > count_before && ! is_space[(int) xbuf[totlen - 1]])
-               {
-                 totlen--;
-               }
-           }
-
-         if (ap->stringify != 0)
-           {
-             assertSet(arg);
-             memcpy (xbuf + totlen,
-                     ARG_BASE + arg->stringified,
-                     size_fromInt (arg->stringified_length));
-             totlen += arg->stringified_length;
-           }
-         else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
-           {
-             char *p1;
-             char *l1;
-
-             assertSet (arg);
-
-             p1 = ARG_BASE + arg->raw;
-             l1 = p1 + arg->raw_length;
-
-             if (ap->raw_before)
-               {
-                 while (p1 != l1 && is_space[(int) *p1])
-                   {
-                     p1++;
-                   }
-
-                 while (p1 != l1 && is_idchar[(int) *p1])
-                   {
-                     xbuf[totlen++] = *p1++;
-                   }
-
-                 /* Delete any no-reexpansion marker that follows
-                    an identifier at the beginning of the argument
-                    if the argument is concatenated with what precedes it.  */
-                 if (p1[0] == '@' && p1[1] == '-')
-                   p1 += 2;
-               }
-             if (ap->raw_after)
-               {
-                 /* Arg is concatenated after: delete trailing whitespace,
-                    whitespace markers, and no-reexpansion markers.  */
-                 while (p1 != l1)
-                   {
-                     if (is_space[(int) l1[-1]]) l1--;
-                     else if (l1[-1] == '-')
-                       {
-                         char *p2 = l1 - 1;
-                         /* If a `-' is preceded by an odd number of newlines then it
-                            and the last newline are a no-reexpansion marker.  */
-                         while (p2 != p1 && p2[-1] == '\n')
-                           {
-                             p2--;
-                           }
-
-                         if (((l1 - 1 - p2) & 1) != 0)
-                           {
-                             l1 -= 2;
-                           }
-                         else
-                           {
-                             /*@innerbreak@*/ break;
-                           }
-                       }
-                     else
-                       {
-                         /*@innerbreak@*/ break;
-                       }
-                   }
-               }
-
-             memcpy (xbuf + totlen, p1, size_fromInt (l1 - p1));
-             totlen += l1 - p1;
-           }
-         else
-           {
-             char *expanded;
-
-             assertSet (arg);
-             expanded = ARG_BASE + arg->expanded;
-
-             if (!ap->raw_before && totlen > 0
-                 && (arg->expand_length != 0)
-                 && !cppReader_isTraditional(pfile)
-                 && unsafe_chars (xbuf[totlen-1], expanded[0]))
-               {
-                 xbuf[totlen++] = '@';
-                 xbuf[totlen++] = ' ';
-               }
-
-             memcpy (xbuf + totlen, expanded,
-                     size_fromInt (arg->expand_length));
-             totlen += arg->expand_length;
-
-             if (!ap->raw_after && totlen > 0
-                 && offset < size_toInt (defn->length)
-                 && !cppReader_isTraditional(pfile)
-                 && unsafe_chars (xbuf[totlen-1], exp[offset]))
-               {
-                 xbuf[totlen++] = '@';
-                 xbuf[totlen++] = ' ';
-               }
-
-             /* If a macro argument with newlines is used multiple times,
-                then only expand the newlines once.  This avoids creating
-                output lines which don't correspond to any input line,
-                which confuses gdb and gcov.  */
-             if (arg->use_count > 1 && arg->newlines > 0)
-               {
-                 /* Don't bother doing change_newlines for subsequent
-                    uses of arg.  */
-                 arg->use_count = 1;
-                 arg->expand_length
-                   = change_newlines (expanded, arg->expand_length);
-               }
-           }
-
-         if (totlen > xbuf_len)
-           abort ();
-       }
-
-      /* if there is anything left of the definition
-        after handling the arg list, copy that in too.  */
-
-      for (i = offset; i < size_toInt (defn->length); i++)
-       {
-         /* if we've reached the end of the macro */
-         if (exp[i] == ')')
-           rest_zero = 0;
-         if (! (rest_zero && last_ap != NULL && last_ap->rest_args
-                && last_ap->raw_after))
-           xbuf[totlen++] = exp[i];
-       }
-
-      xbuf[totlen] = '\0';
-      xbuf_len = totlen;
-    }
-
-  pfile->output_escapes--;
-
-  /* Now put the expansion on the input stack
-     so our caller will commence reading from it.  */
-  push_macro_expansion (pfile, xbuf, xbuf_len, hp);
-  cppReader_getBuffer (pfile)->has_escapes = 1;
-
-  /* Pop the space we've used in the token_buffer for argument expansion.  */
-  cppReader_setWritten (pfile, old_written);
-
-  /* Recursive macro use sometimes works traditionally.
-     #define foo(x,y) bar (x (y,0), y)
-     foo (foo, baz)  */
-
-  if (!cppReader_isTraditional (pfile))
-    hp->type = T_DISABLED;
-
-  sfree (args);
-}
-
-static void
-push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,
-                     /*@dependent@*/ hashNode hp)
-{
-  cppBuffer *mbuf = cppReader_pushBuffer (pfile, xbuf, xbuf_len);
-
-  if (mbuf == NULL)
-    {
-      return;
-    }
-
-  mbuf->cleanup = cppReader_macroCleanup;
-
-  llassert (mbuf->hnode == NULL);
-  mbuf->hnode = hp;
-
-  /* The first chars of the expansion should be a "@ " added by
-     collect_expansion.  This is to prevent accidental token-pasting
-     between the text preceding the macro invocation, and the macro
-     expansion text.
-
-     We would like to avoid adding unneeded spaces (for the sake of
-     tools that use cpp, such as imake).  In some common cases we can
-     tell that it is safe to omit the space.
-
-     The character before the macro invocation cannot have been an
-     idchar (or else it would have been pasted with the idchars of
-     the macro name).  Therefore, if the first non-space character
-     of the expansion is an idchar, we do not need the extra space
-     to prevent token pasting.
-
-     Also, we don't need the extra space if the first char is '(',
-     or some other (less common) characters.  */
-
-  if (xbuf[0] == '@' && xbuf[1] == ' '
-      && (is_idchar[(int) xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
-         || xbuf[2] == '\"'))
-  {
-    llassert (mbuf->cur != NULL);
-    mbuf->cur += 2;
-  }
-}
-
-
-/* Like cppGetToken, except that it does not read past end-of-line.
-   Also, horizontal space is skipped, and macros are popped.  */
-
-static enum cpp_token
-get_directive_token (cppReader *pfile)
-{
-  for (;;)
-    {
-      size_t old_written = cppReader_getWritten (pfile);
-      enum cpp_token token;
-      cppSkipHspace (pfile);
-      if (cppReader_peekC (pfile) == '\n')
-       {
-         return CPP_VSPACE;
-       }
-
-      token = cppGetToken (pfile);
-
-      switch (token)
-       {
-       case CPP_POP:
-         if (!cppBuffer_isMacro (cppReader_getBuffer (pfile)))
-           return token;
-         /*@fallthrough@*/
-       case CPP_HSPACE:
-       case CPP_COMMENT:
-         cppReader_setWritten (pfile, old_written);
-         /*@switchbreak@*/ break;
-       default:
-         return token;
-       }
-    }
-}
-
-
-/* Handle #include and #import.
-   This function expects to see "fname" or <fname> on the input.
-
-   The input is normally in part of the output_buffer following
-   cppReader_getWritten, and will get overwritten by output_line_command.
-   I.e. in input file specification has been popped by cppReader_handleDirective.
-   This is safe.  */
-
-static int
-do_include (cppReader *pfile, struct directive *keyword,
-           /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
-{
-  bool skip_dirs = (keyword->type == T_INCLUDE_NEXT);
-  cstring fname;
-  char *fbeg, *fend;           /* Beginning and end of fname */
-  enum cpp_token token;
-
-  /* Chain of dirs to search */
-  struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
-  struct file_name_list dsp[1];        /* First in chain, if #include "..." */
-  struct file_name_list *searchptr = NULL;
-  size_t old_written = cppReader_getWritten (pfile);
-
-  int flen;
-
-  int f;                       /* file number */
-  int angle_brackets = 0;      /* 0 for "...", 1 for <...> */
-  f= -1;                       /* JF we iz paranoid! */
-
-  pfile->parsing_include_directive++;
-  token = get_directive_token (pfile);
-  pfile->parsing_include_directive--;
-
-  if (token == CPP_STRING)
-    {
-      /* FIXME - check no trailing garbage */
-      fbeg = pfile->token_buffer + old_written + 1;
-      fend = cppReader_getPWritten (pfile) - 1;
-      if (fbeg[-1] == '<')
-       {
-         angle_brackets = 1;
-         /* If -I-, start with the first -I dir after the -I-.  */
-         if (CPPOPTIONS (pfile)->first_bracket_include != NULL)
-           search_start = CPPOPTIONS (pfile)->first_bracket_include;
-       }
-      /* If -I- was specified, don't search current dir, only spec'd ones.  */
-      else if (!CPPOPTIONS (pfile)->ignore_srcdir)
-       {
-         cppBuffer *fp = CPPBUFFER (pfile);
-         /* We have "filename".  Figure out directory this source
-            file is coming from and put it on the front of the list.  */
-
-         for ( ; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
-           {
-             int n;
-             char *ep,*nam;
-
-             llassert (fp != NULL);
-
-             nam = NULL;
-
-             if (cstring_isDefined (fp->nominal_fname))
-               {
-                 nam = cstring_toCharsSafe (fp->nominal_fname);
-
-                 /* Found a named file.  Figure out dir of the file,
-                    and put it in front of the search list.  */
-                 dsp[0].next = search_start;
-                 search_start = dsp;
-
-#ifndef VMS
-                 ep = strrchr (nam, CONNECTCHAR);
-#else                          /* VMS */
-                 ep = strrchr (nam, ']');
-                 if (ep == NULL) ep = strrchr (nam, '>');
-                 if (ep == NULL) ep = strrchr (nam, ':');
-                 if (ep != NULL) ep++;
-#endif                         /* VMS */
-                 if (ep != NULL)
-                   {
-                     char save;
-
-                     n = ep - nam;
-                     save = nam[n];
-                     nam[n] = '\0';
-
-                     /*@-onlytrans@*/ /* This looks like a memory leak... */ 
-                     dsp[0].fname = cstring_fromCharsNew (nam); /* evs 2000-07-20: was fromChars */
-                     /*@=onlytrans@*/
-                     nam[n] = save;
-
-                     if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len)
-                       pfile->max_include_len = n + INCLUDE_LEN_FUDGE;
-                   }
-                 else
-                   {
-                     dsp[0].fname = cstring_undefined; /* Current directory */
-                   }
-
-                 dsp[0].got_name_map = 0;
-                 break;
-               }
-           }
-       }
-      else
-       {
-         ;
-       }
-    }
-#ifdef VMS
-  else if (token == CPP_NAME)
-    {
-      /*
-       * Support '#include xyz' like VAX-C to allow for easy use of all the
-       * decwindow include files. It defaults to '#include <xyz.h>' (so the
-       * code from case '<' is repeated here) and generates a warning.
-       */
-      cppReader_warning (pfile,
-                  "VAX-C-style include specification found, use '#include <filename.h>' !");
-      angle_brackets = 1;
-      /* If -I-, start with the first -I dir after the -I-.  */
-      if (CPPOPTIONS (pfile)->first_bracket_include)
-       search_start = CPPOPTIONS (pfile)->first_bracket_include;
-      fbeg = pfile->token_buffer + old_written;
-      fend = cppReader_getPWritten (pfile);
-    }
-#endif
-  else
-    {
-      cppReader_error (pfile,
-                message ("Preprocessor command #%s expects \"FILENAME\" or <FILENAME>",
-                         keyword->name));
-
-      cppReader_setWritten (pfile, old_written);
-      cppReader_skipRestOfLine (pfile);
-      return 0;
-    }
-
-  *fend = 0;
-
-  token = get_directive_token (pfile);
-  if (token != CPP_VSPACE)
-    {
-      cppReader_errorLit (pfile,
-                   cstring_makeLiteralTemp ("Junk at end of #include"));
-
-      while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
-       {
-         token = get_directive_token (pfile);
-       }
-    }
-
-  /*
-  ** For #include_next, skip in the search path
-  ** past the dir in which the containing file was found.
-  */
-
-  if (skip_dirs)
-    {
-      cppBuffer *fp = CPPBUFFER (pfile);
-
-      for (; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
-       {
-         llassert (fp != NULL);
-
-         if (fp->fname != NULL)
-           {
-             /* fp->dir is null if the containing file was specified with
-                an absolute file name.  In that case, don't skip anything.  */
-             if (fp->dir == SELF_DIR_DUMMY)
-               {
-                 search_start = CPPOPTIONS (pfile)->include;
-               }
-             else if (fp->dir != NULL)
-               {
-                 search_start = fp->dir->next;
-               }
-             else
-               {
-                 ;
-               }
-
-             break;
-           }
-       }
-    }
-
-  cppReader_setWritten (pfile, old_written);
-
-  flen = fend - fbeg;
-
-  DPRINTF (("fbeg: %s", fbeg));
-
-  if (flen == 0)
-    {
-      cppReader_error (pfile,
-                message ("Empty file name in #%s", keyword->name));
-      return 0;
-    }
-
-  /*
-  ** Allocate this permanently, because it gets stored in the definitions
-  ** of macros.
-  */
-
-  fname = cstring_undefined;
-
-  /* + 2 above for slash and terminating null.  */
-  /* + 2 added for '.h' on VMS (to support '#include filename') */
-
-  /* If specified file name is absolute, just open it.  */
-
-  if (osd_isConnectChar (*fbeg)
-# if defined (WIN32) || defined (OS2)
-      || (*(fbeg + 1) == ':')
-# endif
-      )
-    {
-      fname = cstring_copyLength (fbeg, flen);
-      
-      if (redundant_include_p (pfile, fname))
-       {
-         cstring_free (fname);
-         return 0;
-       }
-      
-      f = open_include_file (pfile, fname, NULL);
-      
-      if (f == IMPORT_FOUND)
-       {
-         return 0;             /* Already included this file */
-       }
-    } 
-  else 
-    {
-      /* Search directory path, trying to open the file.
-        Copy each filename tried into FNAME.  */
-
-      for (searchptr = search_start; searchptr != NULL;
-          searchptr = searchptr->next)
-       {
-         if (!cstring_isEmpty (searchptr->fname))
-           {
-             /* The empty string in a search path is ignored.
-                This makes it possible to turn off entirely
-                a standard piece of the list.  */
-             if (cstring_isEmpty (searchptr->fname))
-               continue;
-             
-             fname = cstring_copy (searchptr->fname);
-             fname = cstring_appendChar (fname, CONNECTCHAR);
-             DPRINTF (("Here: %s", fname));
-           }
-         else
-           {
-             ;
-           }
-         
-         fname = cstring_concatLength (fname, fbeg, flen);
-
-         DPRINTF (("fname: %s", fname));
-         
-         /* Win32 directory fix from Kay Buschner. */
-#if defined (WIN32) || defined (OS2)
-         /* Fix all unixdir slashes to win dir slashes */
-         if (searchptr->fname && (searchptr->fname[0] != 0)) 
-           {
-             cstring_replaceAll (fname, '/', '\\');
-           }
-#endif /* WIN32 */
-
-#ifdef VMS
-         /* Change this 1/2 Unix 1/2 VMS file specification into a
-            full VMS file specification */
-         if (searchptr->fname && (searchptr->fname[0] != 0)) {
-           /* Fix up the filename */
-           hack_vms_include_specification (fname);
-         } else {
-           /* This is a normal VMS filespec, so use it unchanged.  */
-           strncpy (fname, fbeg, flen);
-           fname[flen] = 0;
-           /* if it's '#include filename', add the missing .h */
-           if (strchr (fname,'.') == NULL) {
-             strcat (fname, ".h");
-           }
-         }
-#endif /* VMS */
-         /* ??? There are currently 3 separate mechanisms for avoiding processing
-            of redundant include files: #import, #pragma once, and
-            redundant_include_p.  It would be nice if they were unified.  */
-         
-         if (redundant_include_p (pfile, fname))
-           {
-             cstring_free (fname);
-             return 0;
-           }
-
-         DPRINTF (("Trying: %s", fname));
-
-         f = open_include_file (pfile, fname, searchptr);
-         
-         if (f == IMPORT_FOUND)
-           {
-             return 0;                 /* Already included this file */
-           }
-#ifdef EACCES
-         else if (f == IMPORT_NOT_FOUND && errno == EACCES)
-           {
-             cppReader_warning (pfile,
-                                message ("Header file %s exists, but is not readable", fname));
-           }
-#endif
-         
-         if (f >= 0)
-           {
-             break;
-           }
-       }
-    }
-  
-  if (f < 0)
-    {
-      /* A file that was not found.  */
-      fname = cstring_copyLength (fbeg, flen);
-
-      if (search_start != NULL)
-       {
-         cppReader_error (pfile,
-                          message ("Cannot find include file %s on search path: %x", 
-                                   fname,
-                                   searchPath_unparse (search_start)));
-       }
-      else
-       {
-         cppReader_error (pfile,
-                          message ("No include path in which to find %s", fname));
-       }
-    }
-  else {
-    /*
-    ** Check to see if this include file is a once-only include file.
-    ** If so, give up.
-    */
-
-    struct file_name_list *ptr;
-
-    for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
-      {
-       if (cstring_equal (ptr->fname, fname))
-         {
-           /* This file was included before.  */
-           break;
-         }
-      }
-
-    if (ptr == NULL)
-      {
-       /* This is the first time for this file.  */
-       /* Add it to list of files included.  */
-
-       ptr = (struct file_name_list *) dmalloc (sizeof (*ptr));
-       ptr->control_macro = NULL;
-       ptr->c_system_include_path = NULL;
-       ptr->next = pfile->all_include_files;
-       ptr->fname = fname;
-       ptr->got_name_map = NULL;
-
-       DPRINTF (("Including file: %s", fname));
-       pfile->all_include_files = ptr;
-       assertSet (pfile->all_include_files);
-      }
-
-    if (angle_brackets != 0)
-      {
-       pfile->system_include_depth++;
-      }
-
-    /* Actually process the file */
-    if (cppReader_pushBuffer (pfile, NULL, 0) == NULL)
-      {
-       cstring_free (fname);
-       return 0;
-      }
-
-    if (finclude (pfile, f, fname, is_system_include (pfile, fname),
-                 searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
-      {
-       output_line_command (pfile, 0, enter_file);
-       pfile->only_seen_white = 2;
-      }
-
-    if (angle_brackets)
-      {
-       pfile->system_include_depth--;
-      }
-    /*@-branchstate@*/
-  } /*@=branchstate@*/ 
-
-  return 0;
-}
-
-/* Return nonzero if there is no need to include file NAME
-   because it has already been included and it contains a conditional
-   to make a repeated include do nothing.  */
-
-static bool
-redundant_include_p (cppReader *pfile, cstring name)
-{
-  struct file_name_list *l = pfile->all_include_files;
-
-  for (; l != NULL; l = l->next)
-    {
-      if (cstring_equal (name, l->fname)
-         && (l->control_macro != NULL)
-         && (cppReader_lookup (l->control_macro, -1, -1) != NULL))
-       {
-         return TRUE;
-       }
-    }
-
-  return FALSE;
-}
-
-/* Return nonzero if the given FILENAME is an absolute pathname which
-   designates a file within one of the known "system" include file
-   directories.  We assume here that if the given FILENAME looks like
-   it is the name of a file which resides either directly in a "system"
-   include file directory, or within any subdirectory thereof, then the
-   given file must be a "system" include file.  This function tells us
-   if we should suppress pedantic errors/warnings for the given FILENAME.
-
-   The value is 2 if the file is a C-language system header file
-   for which C++ should (on most systems) assume `extern "C"'.  */
-
-static bool
-is_system_include (cppReader *pfile, cstring filename)
-{
-  struct file_name_list *searchptr;
-
-  for (searchptr = CPPOPTIONS (pfile)->first_system_include;
-       searchptr != NULL;
-       searchptr = searchptr->next)
-    {
-      if (!cstring_isEmpty (searchptr->fname)) {
-       cstring sys_dir = searchptr->fname;
-       int length = cstring_length (sys_dir);
-
-       if (cstring_equalLen (sys_dir, filename, length)
-           && osd_isConnectChar (cstring_getChar (filename, length)))
-         {
-           if (searchptr->c_system_include_path)
-             return 2;
-           else
-             return 1;
-         }
-      }
-    }
-
-  return 0;
-}
-
-/* Convert a character string literal into a nul-terminated string.
-   The input string is [IN ... LIMIT).
-   The result is placed in RESULT.  RESULT can be the same as IN.
-   The value returned in the end of the string written to RESULT,
-   or NULL on error.  */
-
-static /*@null@*/ char *
-convert_string (cppReader *pfile, /*@returned@*/ char *result,
-               char *in, char *limit, int handle_escapes)
-{
-  char c;
-  c = *in++;
-
-  if (c != '\"')
-    {
-      return NULL;
-    }
-
-  while (in < limit)
-    {
-      c = *in++;
-
-      switch (c)
-       {
-       case '\0':
-         return NULL;
-       case '\"':
-         limit = in;
-         /*@switchbreak@*/ break;
-       case '\\':
-         if (handle_escapes)
-           {
-             char *bpc = (char *) in;
-             int i = (char) cppReader_parseEscape (pfile, &bpc);
-             in = (char *) bpc;
-             if (i >= 0)
-               *result++ = (char) c;
-             /*@switchbreak@*/ break;
-           }
-
-         /*@fallthrough@*/
-       default:
-         *result++ = c;
-       }
-    }
-
-  *result = 0;
-  return result;
-}
-
-/*
- * interpret #line command.  Remembers previously seen fnames
- * in its very own hash table.
- */
-
-/*@constant int FNAME_HASHSIZE@*/
-#define FNAME_HASHSIZE 37
-
-static int
-do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
-{
-  cppBuffer *ip = cppReader_getBuffer (pfile);
-  int new_lineno;
-  size_t old_written = cppReader_getWritten (pfile);
-  enum file_change_code file_change = same_file;
-  enum cpp_token token;
-
-  token = get_directive_token (pfile);
-
-  if (token != CPP_NUMBER
-      || !isdigit(pfile->token_buffer[old_written]))
-    {
-      cppReader_errorLit (pfile,
-                   cstring_makeLiteralTemp ("invalid format `#line' command"));
-
-      goto bad_line_directive;
-    }
-
-  /* The Newline at the end of this line remains to be processed.
-     To put the next line at the specified line number,
-     we must store a line number now that is one less.  */
-  new_lineno = atoi (pfile->token_buffer + old_written) - 1;
-  cppReader_setWritten (pfile, old_written);
-
-  /* NEW_LINENO is one less than the actual line number here.  */
-  if (cppReader_isPedantic (pfile) && new_lineno < 0)
-    cppReader_pedwarnLit (pfile,
-                   cstring_makeLiteralTemp ("line number out of range in `#line' command"));
-
-  token = get_directive_token (pfile);
-
-  if (token == CPP_STRING) {
-    char *fname = pfile->token_buffer + old_written;
-    char *end_name;
-    static hashNode fname_table[FNAME_HASHSIZE];
-    hashNode hp; 
-    hashNode *hash_bucket;
-    char *p;
-    size_t num_start;
-    int fname_length;
-
-    /* Turn the file name, which is a character string literal,
-       into a null-terminated string.  Do this in place.  */
-    end_name = convert_string (pfile, fname, fname, cppReader_getPWritten (pfile), 1);
-    if (end_name == NULL)
-      {
-       cppReader_errorLit (pfile,
-                     cstring_makeLiteralTemp ("invalid format `#line' command"));
-       goto bad_line_directive;
-      }
-
-    fname_length = end_name - fname;
-    num_start = cppReader_getWritten (pfile);
-
-    token = get_directive_token (pfile);
-    if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
-      p = pfile->token_buffer + num_start;
-      if (cppReader_isPedantic (pfile))
-       cppReader_pedwarnLit (pfile,
-                       cstring_makeLiteralTemp ("garbage at end of `#line' command"));
-
-      if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
-       {
-         cppReader_errorLit (pfile,
-                       cstring_makeLiteralTemp ("invalid format `#line' command"));
-         goto bad_line_directive;
-       }
-      if (*p == '1')
-       file_change = enter_file;
-      else if (*p == 2)
-       file_change = leave_file;
-      else if (*p == 3)
-       ip->system_header_p = 1;
-      else /* if (*p == 4) */
-       ip->system_header_p = 2;
-
-      cppReader_setWritten (pfile, num_start);
-      token = get_directive_token (pfile);
-      p = pfile->token_buffer + num_start;
-      if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
-       ip->system_header_p = *p == 3 ? 1 : 2;
-       token = get_directive_token (pfile);
-      }
-      if (token != CPP_VSPACE) {
-       cppReader_errorLit (pfile,
-                     cstring_makeLiteralTemp ("invalid format `#line' command"));
-
-       goto bad_line_directive;
-      }
-    }
-
-    hash_bucket =
-      &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
-    for (hp = *hash_bucket; hp != NULL; hp = hp->next)
-      {
-       if (hp->length == fname_length &&
-           strncmp (hp->value.cpval, fname, size_fromInt (fname_length)) == 0) {
-         ip->nominal_fname = cstring_fromChars (hp->value.cpval);
-         break;
-       }
-      }
-
-    if (hp == 0) {
-      /* Didn't find it; cons up a new one.  */
-      hp = (hashNode) dmalloc (sizeof (*hp));
-
-      hp->prev = NULL;
-      hp->bucket_hdr = NULL;
-      hp->type = T_NONE;
-      hp->name = cstring_undefined;
-      hp->next = *hash_bucket;
-
-      *hash_bucket = hp;
-
-      hp->length = fname_length;
-      hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
-      memcpy (hp->value.cpval, fname, size_fromInt (fname_length));
-      hp->value.cpval[fname_length] = '\0';
-      ip->nominal_fname = cstring_fromChars (hp->value.cpval);
-    }
-  }
-  else if (token != CPP_VSPACE && token != CPP_EOF)
-    {
-      cppReader_errorLit (pfile,
-                   cstring_makeLiteralTemp ("invalid format `#line' command"));
-      goto bad_line_directive;
-    }
-  else
-    {
-      ;
-    }
-
-  ip->lineno = new_lineno;
-bad_line_directive:
-  cppReader_skipRestOfLine (pfile);
-  cppReader_setWritten (pfile, old_written);
-  output_line_command (pfile, 0, file_change);
-  return 0;
-}
-
-/*
- * remove the definition of a symbol from the symbol table.
- * according to un*x /lib/cpp, it is not an error to undef
- * something that has no definitions, so it isn't one here either.
- */
-
-static int
-do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
-{
-
-  int sym_length;
-  hashNode hp;
-  char *orig_buf = buf;
-
-  SKIP_WHITE_SPACE (buf);
-
-  sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));
-
-  while ((hp = cppReader_lookup (buf, sym_length, -1)) != NULL)
-    {
-      /* If we are generating additional info for debugging (with -g) we
-        need to pass through all effective #undef commands.  */
-      if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
-       {
-         pass_thru_directive (orig_buf, limit, pfile, keyword);
-       }
-
-      if (hp->type != T_MACRO)
-       {
-         cppReader_warning (pfile,
-                      message ("Undefining preprocessor builtin: %s",
-                               hp->name));
-       }
-
-      cppReader_deleteMacro (hp);
-    }
-
-  if (cppReader_isPedantic (pfile)) {
-    buf += sym_length;
-    SKIP_WHITE_SPACE (buf);
-    if (buf != limit)
-      {
-       cppReader_pedwarnLit (pfile,
-                       cstring_makeLiteralTemp ("garbage after `#undef' directive"));
-      }
-  }
-
-  return 0;
-}
-
-
-/*
- * Report an error detected by the program we are processing.
- * Use the text of the line in the error message.
- * (We use error because it prints the filename & line#.)
- */
-
-static int
-do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,
-         char *buf, char *limit)
-{
-  int length = limit - buf;
-  cstring copy = cstring_copyLength (buf, length);
-  cstring adv = cstring_advanceWhiteSpace (copy);
-
-  cppReader_error (pfile, message ("#error %s", adv));
-  cstring_free (copy);
-  return 0;
-}
-
-/*
- * Report a warning detected by the program we are processing.
- * Use the text of the line in the warning message, then continue.
- * (We use error because it prints the filename & line#.)
- */
-
-static int
-do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,
-           char *buf, char *limit)
-{
-  int length = limit - buf;
-  cstring copy = cstring_copyLength (buf, length);
-  cstring adv = cstring_advanceWhiteSpace (copy);
-  cppReader_warning (pfile, message ("#warning %s", adv));
-  cstring_free (copy);
-  return 0;
-}
-
-
-/* #ident has already been copied to the output file, so just ignore it.  */
-
-static int
-do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword,
-         /*@unused@*/ char *buf, /*@unused@*/ char *limit)
-{
-  /* Allow #ident in system headers, since that's not user's fault.  */
-  if (cppReader_isPedantic (pfile) && !cppReader_getBuffer (pfile)->system_header_p)
-    cppReader_pedwarnLit (pfile,
-                   cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
-
-  /* Leave rest of line to be read by later calls to cppGetToken.  */
-
-  return 0;
-}
-
-/* #pragma and its argument line have already been copied to the output file.
-   Just check for some recognized pragmas that need validation here.  */
-
-static int
-do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,
-          /*@unused@*/ char *buf, /*@unused@*/ char *limit)
-{
-  while (*buf == ' ' || *buf == '\t')
-    {
-      buf++;
-    }
-
-  if (!strncmp (buf, "implementation", 14)) {
-    /* Be quiet about `#pragma implementation' for a file only if it hasn't
-       been included yet.  */
-    struct file_name_list *ptr;
-    char *p = buf + 14, *fname, *inc_fname;
-    int fname_len;
-    SKIP_WHITE_SPACE (p);
-    if (*p == '\n' || *p != '\"')
-      return 0;
-
-    fname = p + 1;
-    p = (char *) strchr (fname, '\"');
-    fname_len = p != NULL ? p - fname : mstring_length (fname);
-
-    for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
-      {
-       inc_fname = (char *) strrchr (cstring_toCharsSafe (ptr->fname), CONNECTCHAR);
-       inc_fname = (inc_fname != NULL)
-         ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
-
-       if ((inc_fname != NULL)
-           && (strncmp (inc_fname, fname, size_fromInt (fname_len)) == 0))
-         {
-           cpp_setLocation (pfile);
-
-           ppllerror (message ("`#pragma implementation' for `%s' appears "
-                               "after file is included",
-                               cstring_fromChars (fname)));
-         }
-      }
-  }
-
-  return 0;
-}
-
-/*
- * handle #if command by
- *   1) inserting special `defined' keyword into the hash table
- *     that gets turned into 0 or 1 by special_symbol (thus,
- *     if the luser has a symbol called `defined' already, it won't
- *      work inside the #if command)
- *   2) rescan the input into a temporary output buffer
- *   3) pass the output buffer to the yacc parser and collect a value
- *   4) clean up the mess left from steps 1 and 2.
- *   5) call conditional_skip to skip til the next #endif (etc.),
- *      or not, depending on the value from step 3.
- */
-
-static int
-do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,
-       char *buf, char *limit)
-{
-  HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
-  conditional_skip (pfile, value == 0, T_IF, NULL);
-  return 0;
-}
-
-/*
- * handle a #elif directive by not changing  if_stack  either.
- * see the comment above do_else.
- */
-
-static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
-                   char *buf, char *limit)
-{
-  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
-    {
-      cppReader_errorLit (pfile,
-                   cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
-      return 0;
-    }
-  else
-    {
-      llassert (pfile->if_stack != NULL);
-
-      if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
-       {
-         cppReader_errorLit (pfile,
-                       cstring_makeLiteralTemp ("`#elif' after `#else'"));
-
-         if (pfile->if_stack->fname != NULL
-             && cppReader_getBuffer (pfile)->fname != NULL
-             && !cstring_equal (pfile->if_stack->fname,
-                                cppReader_getBuffer (pfile)->nominal_fname))
-           fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
-         fprintf (stderr, ")\n");
-       }
-      pfile->if_stack->type = T_ELIF;
-    }
-
-  if (pfile->if_stack->if_succeeded)
-    {
-      skip_if_group (pfile, 0);
-    }
-  else
-    {
-      HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
-      if (value == 0)
-       skip_if_group (pfile, 0);
-      else
-       {
-         ++pfile->if_stack->if_succeeded;      /* continue processing input */
-         output_line_command (pfile, 1, same_file);
-       }
-    }
-
-  return 0;
-}
-
-/*
- * evaluate a #if expression in BUF, of length LENGTH,
- * then parse the result as a C expression and return the value as an int.
- */
-
-static HOST_WIDE_INT
-eval_if_expression (cppReader *pfile,
-                   /*@unused@*/ char *buf,
-                   /*@unused@*/ int length)
-{
-  hashNode save_defined;
-  HOST_WIDE_INT value;
-  size_t old_written = cppReader_getWritten (pfile);
-
-  save_defined = cppReader_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
-  pfile->pcp_inside_if = 1;
-
-  value = cppReader_parseExpression (pfile);
-  pfile->pcp_inside_if = 0;
-
-  /* Clean up special symbol */
-  cppReader_deleteMacro (save_defined);
-
-  cppReader_setWritten (pfile, old_written); /* Pop */
-
-  return value;
-}
-
-/*
- * routine to handle ifdef/ifndef.  Try to look up the symbol,
- * then do or don't skip to the #endif/#else/#elif depending
- * on what directive is actually being processed.
- */
-
-static int
-do_xifdef (cppReader *pfile, struct directive *keyword,
-          /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
-{
-  int skip;
-  cppBuffer *ip = cppReader_getBuffer (pfile);
-  char *ident;
-  int ident_length;
-  enum cpp_token token;
-  int start_of_file = 0;
-  char *control_macro = 0;
-  size_t old_written = cppReader_getWritten (pfile);
-
-  DPRINTF (("do xifdef: %d",
-           keyword->type == T_IFNDEF));
-
-  /* Detect a #ifndef at start of file (not counting comments).  */
-  if (cstring_isDefined (ip->fname) && keyword->type == T_IFNDEF)
-    {
-      start_of_file = pfile->only_seen_white == 2;
-    }
-
-  pfile->no_macro_expand++;
-  token = get_directive_token (pfile);
-  pfile->no_macro_expand--;
-
-  ident = pfile->token_buffer + old_written;
-  ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);
-  cppReader_setWritten (pfile, old_written); /* Pop */
-
-  if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
-    {
-      skip = (keyword->type == T_IFDEF);
-      if (! cppReader_isTraditional (pfile))
-       {
-         cppReader_pedwarn (pfile,
-                      message ("`#%s' with no argument", keyword->name));
-       }
-    }
-  else if (token == CPP_NAME)
-    {
-      hashNode hp = cppReader_lookup (ident, ident_length, -1);
-      skip = (keyword->type == T_IFDEF) 
-       ? (hp == NULL) : (hp != NULL);
-
-      DPRINTF (("hp null: %d / %d / %d",
-               (hp == NULL),
-               (keyword->type == T_IFNDEF),
-               skip));
-               
-      if (start_of_file && !skip)
-       {
-         DPRINTF (("Not skipping!"));
-         control_macro = (char *) dmalloc (size_fromInt (ident_length + 1));
-         memcpy (control_macro, ident, size_fromInt (ident_length + 1));
-       }
-    }
-  else
-    {
-      skip = (keyword->type == T_IFDEF);
-      if (! cppReader_isTraditional (pfile))
-       {
-         cppReader_error (pfile,
-                    message ("`#%s' with invalid argument", keyword->name));
-       }
-    }
-
-  if (!cppReader_isTraditional (pfile))
-    {
-      int c;
-      cppSkipHspace (pfile);
-      c = cppReader_peekC (pfile);
-      if (c != EOF && c != '\n')
-       {
-         cppReader_pedwarn (pfile,
-                            message ("garbage at end of `#%s' argument", keyword->name));
-       }
-    }
-
-  cppReader_skipRestOfLine (pfile);
-
-  DPRINTF (("Conditional skip: %d", skip));
-  conditional_skip (pfile, skip, T_IF, control_macro);
-  return 0;
-}
-
-/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
-   If this is a #ifndef starting at the beginning of a file,
-   CONTROL_MACRO is the macro name tested by the #ifndef.
-   Otherwise, CONTROL_MACRO is 0.  */
-
-static void
-conditional_skip (cppReader *pfile, int skip,
-                 enum node_type type,
-                 /*@dependent@*/ char *control_macro)
-{
-  cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
-
-  temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
-  temp->next = pfile->if_stack;
-  temp->control_macro = control_macro;
-  temp->lineno = 0;
-  temp->if_succeeded = 0;
-
-  pfile->if_stack = temp;
-  pfile->if_stack->type = type;
-
-  if (skip != 0)
-    {
-      skip_if_group (pfile, 0);
-      return;
-    }
-  else
-    {
-      ++pfile->if_stack->if_succeeded;
-      output_line_command (pfile, 1, same_file);
-    }
-}
-
-/*
- * skip to #endif, #else, or #elif.  adjust line numbers, etc.
- * leaves input ptr at the sharp sign found.
- * If ANY is nonzero, return at next directive of any sort.
- */
-
-static void
-skip_if_group (cppReader *pfile, int any)
-{
-  int c;
-  struct directive *kt;
-  cppIfStackFrame *save_if_stack = pfile->if_stack; /* don't pop past here */
-  register int ident_length;
-  char *ident;
-  struct parse_marker line_start_mark;
-
-  parseSetMark (&line_start_mark, pfile);
-
-  if (CPPOPTIONS (pfile)->output_conditionals) {
-    static char failed[] = "#failed\n";
-    cppReader_puts (pfile, failed, sizeof(failed)-1);
-    pfile->lineno++;
-    output_line_command (pfile, 1, same_file);
-  }
-
-beg_of_line:
-  if (CPPOPTIONS (pfile)->output_conditionals)
-    {
-      cppBuffer *pbuf = cppReader_getBuffer (pfile);
-      char *start_line;
-
-      llassert (pbuf->buf != NULL);
-
-      start_line = pbuf->buf + line_start_mark.position;
-      cppReader_puts (pfile, start_line, size_fromInt (pbuf->cur - start_line));
-    }
-
-  parseMoveMark (&line_start_mark, pfile);
-
-  if (!cppReader_isTraditional (pfile))
-    {
-      cppSkipHspace (pfile);
-    }
-
-  c  = cppReader_getC (pfile);
-  if (c == '#')
-    {
-      size_t old_written = cppReader_getWritten (pfile);
-      cppSkipHspace (pfile);
-
-      parse_name (pfile, cppReader_getC (pfile));
-      ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);
-      ident = pfile->token_buffer + old_written;
-      pfile->limit = ident;
-
-      for (kt = directive_table; kt->length >= 0; kt++)
-       {
-         cppIfStackFrame *temp;
-         if (ident_length == kt->length
-             && cstring_equalPrefix (kt->name, cstring_fromChars (ident)))
-           {
-             /* If we are asked to return on next directive, do so now.  */
-             if (any)
-               {
-                 goto done;
-               }
-
-             switch (kt->type)
-               {
-               case T_IF:
-               case T_IFDEF:
-               case T_IFNDEF:
-                 temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
-                 temp->next = pfile->if_stack;
-                 temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
-                 temp->type = kt->type;
-                 temp->lineno = 0;
-                 temp->if_succeeded = 0;
-                 temp->control_macro = NULL;
-
-                 pfile->if_stack = temp;
-                 /*@switchbreak@*/ break;
-               case T_ELSE:
-               case T_ENDIF:
-                 if (cppReader_isPedantic (pfile) && pfile->if_stack != save_if_stack)
-                   validate_else (pfile,
-                                  cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
-                 /*@fallthrough@*/
-               case T_ELIF:
-                 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
-                   {
-                     cppReader_error (pfile,
-                                message ("Preprocessor command #%s is not within a conditional", kt->name));
-                     /*@switchbreak@*/ break;
-                   }
-                 else if (pfile->if_stack == save_if_stack)
-                   {
-                     goto done;                /* found what we came for */
-                   }
-                 else
-                   {
-                     ;
-                   }
-
-                 if (kt->type != T_ENDIF)
-                   {
-                     llassert (pfile->if_stack != NULL);
-
-                     if (pfile->if_stack->type == T_ELSE)
-                       {
-                         cppReader_errorLit (pfile,
-                                       cstring_makeLiteralTemp ("`#else' or `#elif' after `#else'"));
-                       }
-
-                     pfile->if_stack->type = kt->type;
-                     /*@switchbreak@*/ break;
-                   }
-
-                 temp = pfile->if_stack;
-                 llassert (temp != NULL);
-                 pfile->if_stack = temp->next;
-                 sfree (temp);
-                 /*@switchbreak@*/ break;
-               default: ;
-                 /*@-branchstate@*/ 
-               }
-             /*@=branchstate@*/
-             break;
-           }
-         
-         /* Don't let erroneous code go by.  */
-         
-         if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm
-             && cppReader_isPedantic (pfile))
-           {
-             cppReader_pedwarnLit (pfile,
-                                   cstring_makeLiteralTemp ("Invalid preprocessor directive name"));
-           }
-       }
-
-      c = cppReader_getC (pfile);
-    }
-  /* We're in the middle of a line.  Skip the rest of it.  */
-  for (;;) {
-    size_t old;
-
-    switch (c)
-      {
-      case EOF:
-       goto done;
-      case '/':                        /* possible comment */
-       c = skip_comment (pfile, NULL);
-       if (c == EOF)
-         goto done;
-       /*@switchbreak@*/ break;
-      case '\"':
-      case '\'':
-       cppReader_forward (pfile, -1);
-       old = cppReader_getWritten (pfile);
-       (void) cppGetToken (pfile);
-       cppReader_setWritten (pfile, old);
-       /*@switchbreak@*/ break;
-      case '\\':
-       /* Char after backslash loses its special meaning.  */
-       if (cppReader_peekC (pfile) == '\n')
-         {
-           cppReader_forward (pfile, 1);
-         }
-
-       /*@switchbreak@*/ break;
-      case '\n':
-       goto beg_of_line;
-      }
-    c = cppReader_getC (pfile);
-  }
-done:
-  if (CPPOPTIONS (pfile)->output_conditionals) {
-    static char end_failed[] = "#endfailed\n";
-    cppReader_puts (pfile, end_failed, sizeof(end_failed)-1);
-    pfile->lineno++;
-  }
-  pfile->only_seen_white = 1;
-
-  parseGotoMark (&line_start_mark, pfile);
-  parseClearMark (&line_start_mark);
-}
-
-/*
- * handle a #else directive.  Do this by just continuing processing
- * without changing  if_stack ;  this is so that the error message
- * for missing #endif's etc. will point to the original #if.  It
- * is possible that something different would be better.
- */
-
-static int
-do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,
-       /*@unused@*/ char *buf, /*@unused@*/ char *limit)
-{
-  if (cppReader_isPedantic (pfile))
-    {
-      validate_else (pfile, cstring_makeLiteralTemp ("#else"));
-    }
-
-  cppReader_skipRestOfLine (pfile);
-
-  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) {
-    cppReader_errorLit (pfile,
-                 cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
-    return 0;
-  } else {
-    /* #ifndef can't have its special treatment for containing the whole file
-       if it has a #else clause.  */
-
-    llassert (pfile->if_stack != NULL);
-
-    pfile->if_stack->control_macro = 0;
-
-    if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
-      {
-       cpp_setLocation (pfile);
-       genppllerrorhint (FLG_PREPROC,
-                         message ("Pre-processor directive #else after #else"),
-                         message ("%q: Location of match",
-                                  fileloc_unparseRaw (pfile->if_stack->fname,
-                                                      pfile->if_stack->lineno)));
-      }
-
-    pfile->if_stack->type = T_ELSE;
-  }
-
-  if (pfile->if_stack->if_succeeded)
-    skip_if_group (pfile, 0);
-  else {
-    ++pfile->if_stack->if_succeeded;   /* continue processing input */
-    output_line_command (pfile, 1, same_file);
-  }
-
-  return 0;
-}
-
-/*
- * unstack after #endif command
- */
-
-static int
-do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
-         /*@unused@*/ char *buf, /*@unused@*/ char *limit)
-{
-  if (cppReader_isPedantic (pfile))
-    {
-      validate_else (pfile, cstring_makeLiteralTemp ("#endif"));
-    }
-
-  cppReader_skipRestOfLine (pfile);
-
-  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
-    {
-      cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
-    }
-  else
-    {
-      cppIfStackFrame *temp = pfile->if_stack;
-
-      llassert (temp != NULL);
-
-      pfile->if_stack = temp->next;
-      if (temp->control_macro != 0)
-       {
-         /* This #endif matched a #ifndef at the start of the file.
-            See if it is at the end of the file.  */
-         struct parse_marker start_mark;
-         int c;
-
-         parseSetMark (&start_mark, pfile);
-
-         for (;;)
-           {
-             cppSkipHspace (pfile);
-             c = cppReader_getC (pfile);
-
-             if (c != '\n')
-               break;
-           }
-
-         parseGotoMark (&start_mark, pfile);
-         parseClearMark (&start_mark);
-
-         if (c == EOF)
-           {
-             /* If we get here, this #endif ends a #ifndef
-                that contains all of the file (aside from whitespace).
-                Arrange not to include the file again
-                if the macro that was tested is defined.
-
-                Do not do this for the top-level file in a -include or any
-                file in a -imacros.  */
-             struct file_name_list *ifile = pfile->all_include_files;
-
-             for ( ; ifile != NULL; ifile = ifile->next)
-               {
-                 if (cstring_equal (ifile->fname, cppReader_getBuffer (pfile)->fname))
-                   {
-                     ifile->control_macro = temp->control_macro;
-                     break;
-                   }
-               }
-           }
-       }
-
-      sfree (temp);
-      output_line_command (pfile, 1, same_file);
-    }
-  return 0;
-}
-
-/* When an #else or #endif is found while skipping failed conditional,
-   if -pedantic was specified, this is called to warn about text after
-   the command name.  P points to the first char after the command name.  */
-
-static void
-validate_else (cppReader *pfile, cstring directive)
-{
-  int c;
-  cppSkipHspace (pfile);
-  c = cppReader_peekC (pfile);
-  if (c != EOF && c != '\n')
-    {
-      cppReader_pedwarn (pfile,
-                  message ("text following `%s' violates ANSI standard", directive));
-    }
-}
-
-/*
-** Get the next token, and add it to the text in pfile->token_buffer.
-** Return the kind of token we got.
-*/
-
-enum cpp_token
-cppGetToken (cppReader *pfile)
-{
-  int c, c2, c3;
-  size_t old_written = 0;
-  int start_line, start_column;
-  enum cpp_token token;
-  struct cppOptions *opts = CPPOPTIONS (pfile);
-  cppReader_getBuffer (pfile)->prev = cppReader_getBuffer (pfile)->cur;
-
-get_next:
-  c = cppReader_getC (pfile);
-
-  if (c == EOF)
-    {
-    handle_eof:
-      if (cppReader_getBuffer (pfile)->seen_eof)
-       {
-         cppBuffer *buf = cppReader_popBuffer (pfile);
-
-         if (buf != cppReader_nullBuffer (pfile))
-           {
-             goto get_next;
-           }
-         else
-           {
-             return CPP_EOF;
-           }
-       }
-      else
-       {
-         cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
-         cppReader_getBuffer (pfile)->seen_eof = 1;
-
-         if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname)
-             && next_buf != cppReader_nullBuffer (pfile))
-           {
-             /* We're about to return from an #include file.
-                Emit #line information now (as part of the CPP_POP) result.
-                But the #line refers to the file we will pop to.  */
-             cppBuffer *cur_buffer = CPPBUFFER (pfile);
-             CPPBUFFER (pfile) = next_buf;
-             pfile->input_stack_listing_current = 0;
-             output_line_command (pfile, 0, leave_file);
-             CPPBUFFER (pfile) = cur_buffer;
-           }
-         return CPP_POP;
-       }
-    }
-  else
-    {
-      long newlines;
-      struct parse_marker start_mark;
-
-      switch (c)
-       {
-       case '/':
-         if (cppReader_peekC (pfile) == '=')
-           {
-             goto op2;
-           }
-
-         if (opts->put_out_comments)
-           {
-             parseSetMark (&start_mark, pfile);
-           }
-
-         newlines = 0;
-         cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
-                                  &start_line, &start_column);
-         c = skip_comment (pfile, &newlines);
-
-         if (opts->put_out_comments && (c == '/' || c == EOF))
-           {
-             assertSet (&start_mark);
-             parseClearMark (&start_mark);
-           }
-
-         if (c == '/')
-           goto randomchar;
-         if (c == EOF)
-           {
-             cppReader_errorWithLine (pfile, start_line, start_column,
-                                      cstring_makeLiteral ("Unterminated comment"));
-             goto handle_eof;
-           }
-         c = '/';  /* Initial letter of comment.  */
-       return_comment:
-         /* Comments are equivalent to spaces.
-            For -traditional, a comment is equivalent to nothing.  */
-
-         if (opts->put_out_comments)
-           {
-             enum cpp_token res;
-
-             assertSet (&start_mark);
-             res = cpp_handleComment (pfile, &start_mark);
-             pfile->lineno += newlines;
-             return res;
-           }
-         else if (cppReader_isTraditional (pfile))
-           {
-             return CPP_COMMENT;
-           }
-         else
-           {
-             cppReader_reserve(pfile, 1);
-             cppReader_putCharQ (pfile, ' ');
-             return CPP_HSPACE;
-           }
-
-       case '#':
-         if (!pfile->only_seen_white)
-           {
-             goto randomchar;
-           }
-
-         if (cppReader_handleDirective (pfile))
-           {
-             return CPP_DIRECTIVE;
-           }
-
-         pfile->only_seen_white = 0;
-         return CPP_OTHER;
-
-       case '\"':
-       case '\'':
-         /* A single quoted string is treated like a double -- some
-            programs (e.g., troff) are perverse this way */
-         cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
-                                  &start_line, &start_column);
-         old_written = cppReader_getWritten (pfile);
-       string:
-         cppReader_putChar (pfile, c);
-         while (TRUE)
-           {
-             int cc = cppReader_getC (pfile);
-             if (cc == EOF)
-               {
-                 if (cppBuffer_isMacro (CPPBUFFER (pfile)))
-                   {
-                     /* try harder: this string crosses a macro expansion
-                        boundary.  This can happen naturally if -traditional.
-                        Otherwise, only -D can make a macro with an unmatched
-                        quote.  */
-                     cppBuffer *next_buf
-                       = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
-                     (*cppReader_getBuffer (pfile)->cleanup)
-                       (cppReader_getBuffer (pfile), pfile);
-                     CPPBUFFER (pfile) = next_buf;
-                     continue;
-                   }
-                 if (!cppReader_isTraditional (pfile))
-                   {
-                     cpp_setLocation (pfile);
-
-                     setLine (long_toInt (start_line));
-                     setColumn (long_toInt (start_column));
-
-                     if (pfile->multiline_string_line != long_toInt (start_line)
-                         && pfile->multiline_string_line != 0)
-                       {
-                         genppllerrorhint
-                           (FLG_PREPROC,
-                            message ("Unterminated string or character constant"),
-                            message ("%q: Possible real start of unterminated constant",
-                                     fileloc_unparseRaw 
-                                     (fileloc_filename (g_currentloc),
-                                      pfile->multiline_string_line)));
-                         pfile->multiline_string_line = 0;
-                       }
-                     else
-                       {
-                         genppllerror
-                           (FLG_PREPROC,
-                            message ("Unterminated string or character constant"));
-                       }
-                   }
-                 /*@loopbreak@*/ break;
-               }
-             cppReader_putChar (pfile, cc);
-             switch (cc)
-               {
-               case '\n':
-                 /* Traditionally, end of line ends a string constant with
-                    no error.  So exit the loop and record the new line.  */
-                 if (cppReader_isTraditional (pfile))
-                   goto while2end;
-                 if (c == '\'')
-                   {
-                     goto while2end;
-                   }
-                 if (cppReader_isPedantic (pfile)
-                     && pfile->multiline_string_line == 0)
-                   {
-                     cppReader_pedwarnWithLine
-                       (pfile, long_toInt (start_line),
-                        long_toInt (start_column),
-                        cstring_makeLiteral ("String constant runs past end of line"));
-                   }
-                 if (pfile->multiline_string_line == 0)
-                   {
-                     pfile->multiline_string_line = start_line;
-                   }
-
-                 /*@switchbreak@*/ break;
-
-               case '\\':
-                 cc = cppReader_getC (pfile);
-                 if (cc == '\n')
-                   {
-                     /* Backslash newline is replaced by nothing at all.  */
-                     cppReader_adjustWritten (pfile, -1);
-                     pfile->lineno++;
-                   }
-                 else
-                   {
-                     /* ANSI stupidly requires that in \\ the second \
-                        is *not* prevented from combining with a newline.  */
-                     NEWLINE_FIX1(cc);
-                     if (cc != EOF)
-                       cppReader_putChar (pfile, cc);
-                   }
-                 /*@switchbreak@*/ break;
-
-               case '\"':
-               case '\'':
-                 if (cc == c)
-                   goto while2end;
-                 /*@switchbreak@*/ break;
-               }
-           }
-       while2end:
-         pfile->lineno += count_newlines (pfile->token_buffer + old_written,
-                                          cppReader_getPWritten (pfile));
-         pfile->only_seen_white = 0;
-         return c == '\'' ? CPP_CHAR : CPP_STRING;
-
-       case '$':
-         if (!opts->dollars_in_ident)
-           goto randomchar;
-         goto letter;
-
-       case ':':
-         if (opts->cplusplus && cppReader_peekC (pfile) == ':')
-           goto op2;
-         goto randomchar;
-
-       case '&':
-       case '+':
-       case '|':
-         NEWLINE_FIX;
-         c2 = cppReader_peekC (pfile);
-         if (c2 == c || c2 == '=')
-           goto op2;
-         goto randomchar;
-
-       case '*':
-       case '!':
-       case '%':
-       case '=':
-       case '^':
-         NEWLINE_FIX;
-         if (cppReader_peekC (pfile) == '=')
-           goto op2;
-         goto randomchar;
-
-       case '-':
-         NEWLINE_FIX;
-         c2 = cppReader_peekC (pfile);
-         if (c2 == '-' && opts->chill)
-           {
-             /* Chill style comment */
-             if (opts->put_out_comments)
-               {
-                 parseSetMark (&start_mark, pfile);
-               }
-
-             cppReader_forward (pfile, 1);  /* Skip second '-'.  */
-
-             for (;;)
-               {
-                 c = cppReader_getC (pfile);
-                 if (c == EOF)
-                   /*@loopbreak@*/ break;
-                 if (c == '\n')
-                   {
-                     /* Don't consider final '\n' to be part of comment.  */
-                     cppReader_forward (pfile, -1);
-                     /*@loopbreak@*/ break;
-                   }
-               }
-             c = '-';
-             goto return_comment;
-           }
-         if (c2 == '-' || c2 == '=' || c2 == '>')
-           goto op2;
-         goto randomchar;
-
-       case '<':
-         if (pfile->parsing_include_directive)
-           {
-             for (;;)
-               {
-                 cppReader_putChar (pfile, c);
-                 if (c == '>')
-                   /*@loopbreak@*/ break;
-                 c = cppReader_getC (pfile);
-                 NEWLINE_FIX1 (c);
-                 if (c == '\n' || c == EOF)
-                   {
-                     cppReader_errorLit (pfile,
-                                   cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));
-                     /*@loopbreak@*/ break;
-                   }
-               }
-             return CPP_STRING;
-           }
-         /*@fallthrough@*/
-       case '>':
-         NEWLINE_FIX;
-         c2 = cppReader_peekC (pfile);
-         if (c2 == '=')
-           goto op2;
-         if (c2 != c)
-           goto randomchar;
-         cppReader_forward (pfile, 1);
-         cppReader_reserve (pfile, 4);
-         cppReader_putChar (pfile, c);
-         cppReader_putChar (pfile, c2);
-         NEWLINE_FIX;
-         c3 = cppReader_peekC (pfile);
-         if (c3 == '=')
-           cppReader_putCharQ (pfile, cppReader_getC (pfile));
-         cppReader_nullTerminateQ (pfile);
-         pfile->only_seen_white = 0;
-         return CPP_OTHER;
-
-       case '@':
-         if (cppReader_getBuffer (pfile)->has_escapes)
-           {
-             c = cppReader_getC (pfile);
-             if (c == '-')
-               {
-                 if (pfile->output_escapes)
-                   cppReader_puts (pfile, "@-", 2);
-                 parse_name (pfile, cppReader_getC (pfile));
-                 return CPP_NAME;
-               }
-             else if (is_space [c])
-               {
-                 cppReader_reserve (pfile, 2);
-                 if (pfile->output_escapes)
-                   cppReader_putCharQ (pfile, '@');
-                 cppReader_putCharQ (pfile, c);
-                 return CPP_HSPACE;
-               }
-             else
-               {
-                 ;
-               }
-           }
-         if (pfile->output_escapes)
-           {
-             cppReader_puts (pfile, "@@", 2);
-             return CPP_OTHER;
-           }
-         goto randomchar;
-       case '.':
-         NEWLINE_FIX;
-         c2 = cppReader_peekC (pfile);
-         if (isdigit(c2))
-           {
-             cppReader_reserve(pfile, 2);
-             cppReader_putCharQ (pfile, '.');
-             c = cppReader_getC (pfile);
-             goto number;
-           }
-
-         /* FIXME - misses the case "..\\\n." */
-         if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
-           {
-             cppReader_reserve(pfile, 4);
-             cppReader_putCharQ (pfile, '.');
-             cppReader_putCharQ (pfile, '.');
-             cppReader_putCharQ (pfile, '.');
-             cppReader_forward (pfile, 2);
-             cppReader_nullTerminateQ (pfile);
-             pfile->only_seen_white = 0;
-             return CPP_3DOTS;
-           }
-         goto randomchar;
-       op2:
-         token = CPP_OTHER;
-         pfile->only_seen_white = 0;
-        op2any:
-         cppReader_reserve(pfile, 3);
-         cppReader_putCharQ (pfile, c);
-         cppReader_putCharQ (pfile, cppReader_getC (pfile));
-         cppReader_nullTerminateQ (pfile);
-         return token;
-
-       case 'L':
-         NEWLINE_FIX;
-         c2 = cppReader_peekC (pfile);
-         if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
-           {
-             cppReader_putChar (pfile, c);
-             c = cppReader_getC (pfile);
-             goto string;
-           }
-         goto letter;
-
-       case '0': case '1': case '2': case '3': case '4':
-       case '5': case '6': case '7': case '8': case '9':
-       number:
-         c2  = '.';
-         for (;;)
-           {
-             cppReader_reserve (pfile, 2);
-             cppReader_putCharQ (pfile, c);
-             NEWLINE_FIX;
-             c = cppReader_peekC (pfile);
-             if (c == EOF)
-               /*@loopbreak@*/ break;
-             if (!is_idchar[c] && c != '.'
-                 && ((c2 != 'e' && c2 != 'E'
-                      && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
-                     || (c != '+' && c != '-')))
-               /*@loopbreak@*/ break;
-             cppReader_forward (pfile, 1);
-             c2= c;
-           }
-
-         cppReader_nullTerminateQ (pfile);
-         pfile->only_seen_white = 0;
-         return CPP_NUMBER;
-
-       case 'b': case 'c': case 'd': case 'h': case 'o':
-       case 'B': case 'C': case 'D': case 'H': case 'O':
-         if (opts->chill && cppReader_peekC (pfile) == '\'')
-           {
-             pfile->only_seen_white = 0;
-             cppReader_reserve (pfile, 2);
-             cppReader_putCharQ (pfile, c);
-             cppReader_putCharQ (pfile, '\'');
-             cppReader_forward (pfile, 1);
-             for (;;)
-               {
-                 c = cppReader_getC (pfile);
-                 if (c == EOF)
-                   goto chill_number_eof;
-                 if (!is_idchar[c])
-                   {
-                     if (c == '\\' && cppReader_peekC (pfile) == '\n')
-                       {
-                         cppReader_forward (pfile, 2);
-                         continue;
-                       }
-                     /*@loopbreak@*/ break;
-                   }
-                 cppReader_putChar (pfile, c);
-               }
-             if (c == '\'')
-               {
-                 cppReader_reserve (pfile, 2);
-                 cppReader_putCharQ (pfile, c);
-                 cppReader_nullTerminateQ (pfile);
-                 return CPP_STRING;
-               }
-             else
-               {
-                 cppReader_forward (pfile, -1);
-               chill_number_eof:
-                 cppReader_nullTerminate (pfile);
-                 return CPP_NUMBER;
-               }
-           }
-         else
-           goto letter;
-       case '_':
-       case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
-       case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
-       case 'r': case 's': case 't': case 'u': case 'v': case 'w':
-       case 'x': case 'y': case 'z':
-       case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
-       case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
-       case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
-       case 'Y': case 'Z':
-        letter:
-          {
-           hashNode hp;
-           char *ident;
-           size_t before_name_written = cppReader_getWritten (pfile);
-           int ident_len;
-           parse_name (pfile, c);
-           pfile->only_seen_white = 0;
-           if (pfile->no_macro_expand)
-             {
-               return CPP_NAME;
-             }
-
-           ident = pfile->token_buffer + before_name_written;
-           ident_len = (cppReader_getPWritten (pfile)) - ident;
-
-           hp = cppReader_lookupExpand (ident, ident_len, -1);
-
-           if (hp == NULL)
-             {
-               return CPP_NAME;
-             }
-
-           if (hp->type == T_DISABLED)
-             {
-               if (pfile->output_escapes)
-                 { /* Return "@-IDENT", followed by '\0'.  */
-                   int i;
-                   cppReader_reserve (pfile, 3);
-                   ident = pfile->token_buffer + before_name_written;
-                   cppReader_adjustWritten (pfile, 2);
-
-                   for (i = ident_len; i >= 0; i--)
-                     {
-                       ident[i+2] = ident[i];
-                     }
-
-                   ident[0] = '@';
-                   ident[1] = '-';
-                 }
-               return CPP_NAME;
-             }
-
-           /* If macro wants an arglist, verify that a '(' follows.
-              first skip all whitespace, copying it to the output
-              after the macro name.  Then, if there is no '(',
-              decide this is not a macro call and leave things that way.  */
-
-           if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
-             {
-               struct parse_marker macro_mark;
-               int is_macro_call;
-
-               while (cppBuffer_isMacro (CPPBUFFER (pfile)))
-                 {
-                   cppBuffer *next_buf;
-                   cppSkipHspace (pfile);
-                   if (cppReader_peekC (pfile) != EOF)
-                     {
-                       /*@loopbreak@*/ break;
-                     }
-
-                 next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
-                 (*cppReader_getBuffer (pfile)->cleanup) (cppReader_getBuffer (pfile), pfile);
-                 CPPBUFFER (pfile) = next_buf;
-                 }
-
-               parseSetMark (&macro_mark, pfile);
-
-               for (;;)
-                 {
-                   cppSkipHspace (pfile);
-                   c = cppReader_peekC (pfile);
-                   is_macro_call = c == '(';
-                   if (c != '\n')
-                     /*@loopbreak@*/ break;
-                   cppReader_forward (pfile, 1);
-                 }
-
-               if (!is_macro_call)
-                 {
-                   parseGotoMark (&macro_mark, pfile);
-                 }
-
-               parseClearMark (&macro_mark);
-
-               if (!is_macro_call)
-                 {
-                   return CPP_NAME;
-                 }
-             }
-           /* This is now known to be a macro call.  */
-
-           /* it might not actually be a macro.  */
-           if (hp->type != T_MACRO)
-             {
-               size_t xbuf_len;
-               char *xbuf;
-
-               cppReader_setWritten (pfile, before_name_written);
-               special_symbol (hp, pfile);
-               xbuf_len = cppReader_getWritten (pfile) - before_name_written;
-               xbuf = (char *) dmalloc (xbuf_len + 1);
-               cppReader_setWritten (pfile, before_name_written);
-               memcpy (xbuf, cppReader_getPWritten (pfile), xbuf_len + 1);
-               push_macro_expansion (pfile, xbuf, xbuf_len, hp);
-             }
-           else
-             {
-               /* Expand the macro, reading arguments as needed,
-                  and push the expansion on the input stack.  */
-                               macroexpand (pfile, hp);
-               cppReader_setWritten (pfile, before_name_written);
-             }
-
-           /* An extra "@ " is added to the end of a macro expansion
-              to prevent accidental token pasting.  We prefer to avoid
-              unneeded extra spaces (for the sake of cpp-using tools like
-              imake).  Here we remove the space if it is safe to do so.  */
-
-           llassert (pfile->buffer->rlimit != NULL);
-
-           if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
-               && pfile->buffer->rlimit[-2] == '@'
-               && pfile->buffer->rlimit[-1] == ' ')
-             {
-               int c1 = pfile->buffer->rlimit[-3];
-               int cl2 = cppBufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
-
-               if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
-                 pfile->buffer->rlimit -= 2;
-             }
-         }
-         goto get_next;
-
-
-       case ' ':  case '\t':  case '\v':  case '\r':
-         for (;;)
-           {
-             cppReader_putChar (pfile, c);
-             c = cppReader_peekC (pfile);
-             if (c == EOF || !is_hor_space[c])
-               /*@loopbreak@*/ break;
-             cppReader_forward (pfile, 1);
-           }
-         return CPP_HSPACE;
-
-        case '\\':
-         c2 = cppReader_peekC (pfile);
-         if (c2 != '\n')
-           goto randomchar;
-         token = CPP_HSPACE;
-         goto op2any;
-
-       case '\n':
-         cppReader_putChar (pfile, c);
-         if (pfile->only_seen_white == 0)
-           pfile->only_seen_white = 1;
-         pfile->lineno++;
-         output_line_command (pfile, 1, same_file);
-         return CPP_VSPACE;
-
-       case '(': token = CPP_LPAREN;    goto char1;
-       case ')': token = CPP_RPAREN;    goto char1;
-       case '{': token = CPP_LBRACE;    goto char1;
-       case '}': token = CPP_RBRACE;    goto char1;
-       case ',': token = CPP_COMMA;     goto char1;
-       case ';': token = CPP_SEMICOLON; goto char1;
-
-       randomchar:
-       default:
-         token = CPP_OTHER;
-       char1:
-         pfile->only_seen_white = 0;
-         cppReader_putChar (pfile, c);
-         return token;
-       }
-    }
-
-  BADBRANCH;
-  /*@notreached@*/
-}
-
-/* Parse an identifier starting with C.  */
-
-void
-parse_name (cppReader *pfile, int c)
-{
-  for (;;)
-    {
-      if (!is_idchar[c])
-       {
-         if (c == '\\' && cppReader_peekC (pfile) == '\n')
-           {
-             cppReader_forward (pfile, 2);
-             continue;
-           }
-
-         cppReader_forward (pfile, -1);
-         break;
-       }
-
-      if (c == '$' && cppReader_isPedantic (pfile))
-       {
-         cppReader_pedwarnLit (pfile,
-                         cstring_makeLiteralTemp ("`$' in identifier"));
-       }
-
-      cppReader_reserve(pfile, 2); /* One more for final NUL.  */
-      cppReader_putCharQ (pfile, c);
-      c = cppReader_getC (pfile);
-
-      if (c == EOF)
-       break;
-    }
-
-  cppReader_nullTerminateQ (pfile);
-}
-
-/* The file_name_map structure holds a mapping of file names for a
-   particular directory.  This mapping is read from the file named
-   FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
-   map filenames on a file system with severe filename restrictions,
-   such as DOS.  The format of the file name map file is just a series
-   of lines with two tokens on each line.  The first token is the name
-   to map, and the second token is the actual name to use.  */
-
-struct file_name_map
-{
-  struct file_name_map *map_next;
-  cstring map_from;
-  cstring map_to;
-};
-
-/*@constant observer char *FILE_NAME_MAP_FILE*/
-#define FILE_NAME_MAP_FILE "header.gcc"
-
-/* Read a space delimited string of unlimited length from a stdio
-   file.  */
-
-static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
-{
-  char *alloc, *set;
-  size_t len;
-
-  len = 20;
-  set = alloc = dmalloc (len + 1);
-
-  if (!is_space[ch])
-    {
-      *set++ = ch;
-      while ((ch = getc (f)) != EOF && ! is_space[ch])
-       {
-         if (set - alloc == size_toInt (len))
-           {
-             len *= 2;
-             alloc = drealloc (alloc, len + 1);
-             set = alloc + len / 2;
-             /*@-branchstate@*/ }
-
-         *set++ = ch;
-       } /*@=branchstate@*/
-    }
-  *set = '\0';
-  check (ungetc (ch, f) != EOF);
-
-  return cstring_fromChars (alloc);
-}
-
-/* This structure holds a linked list of file name maps, one per directory.  */
-
-struct file_name_map_list
-{
-  struct file_name_map_list *map_list_next;
-  cstring map_list_name;
-  struct file_name_map *map_list_map;
-};
-
-/* Read the file name map file for DIRNAME.  */
-
-static struct file_name_map *
-read_name_map (cppReader *pfile, cstring dirname)
-{
-  struct file_name_map_list *map_list_ptr;
-  cstring name;
-  FILE *f;
-
-  for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
-       map_list_ptr != NULL;
-       map_list_ptr = map_list_ptr->map_list_next)
-    {
-      if (cstring_equal (map_list_ptr->map_list_name, dirname))
-       {
-         return map_list_ptr->map_list_map;
-       }
-    }
-
-  map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
-  map_list_ptr->map_list_name = cstring_copy (dirname);
-  map_list_ptr->map_list_map = NULL;
-
-  name = cstring_copy (dirname);
-
-  if (cstring_length (dirname) > 0)
-    {
-      name = cstring_appendChar (name, CONNECTCHAR);
-    }
-
-  name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
-
-  f = fileTable_openFile (context_fileTable (), name, "r");
-  cstring_free (name);
-
-  if (f == NULL)
-    {
-      map_list_ptr->map_list_map = NULL;
-    }
-  else
-    {
-      int ch;
-
-      while ((ch = getc (f)) != EOF)
-       {
-         cstring from, to;
-         struct file_name_map *ptr;
-
-         if (is_space[ch])
-           {
-             continue;
-           }
-
-         from = read_filename_string (ch, f);
-         while ((ch = getc (f)) != EOF && is_hor_space[ch])
-           {
-             ;
-           }
-
-         to = read_filename_string (ch, f);
-
-         ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
-         ptr->map_from = from;
-
-         /* Make the real filename absolute.  */
-         if (cstring_length (to) > 1 
-             && osd_isConnectChar (cstring_firstChar (to)))
-           {
-             ptr->map_to = to;
-           }
-         else
-           {
-             ptr->map_to = cstring_copy (dirname);
-             ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
-             ptr->map_to = cstring_concatFree (ptr->map_to, to);
-           }
-
-         ptr->map_next = map_list_ptr->map_list_map;
-         map_list_ptr->map_list_map = ptr;
-
-         while ((ch = getc (f)) != '\n')
-           {
-             if (ch == EOF)
-               {
-                 /*@innerbreak@*/ break;
-               }
-           }
-       }
-
-      assertSet (map_list_ptr->map_list_map);
-      check (fileTable_closeFile (context_fileTable (),f) == 0);
-    }
-
-  map_list_ptr->map_list_next = pfile->opts->map_list;
-  pfile->opts->map_list = map_list_ptr;
-
-  return map_list_ptr->map_list_map;
-}
-
-/* Try to open include file FILENAME.  SEARCHPTR is the directory
-   being tried from the include file search path.  This function maps
-   filenames on file systems based on information read by
-   read_name_map.  */
-
-static int
-open_include_file (cppReader *pfile,
-                  cstring fname,
-                  struct file_name_list *searchptr)
-{
-  char *filename = cstring_toCharsSafe (fname);
-  struct file_name_map *map;
-  char *from;
-  char *p, *dir;
-
-  cstring_markOwned (fname);
-
-  cpp_setLocation (pfile);
-
-  if (context_getFlag (FLG_NEVERINCLUDE))
-    {
-      if (isHeaderFile (fname))
-       {
-         return SKIP_INCLUDE;
-       }
-    }
-
-  if ((searchptr != NULL) && ! searchptr->got_name_map)
-    {
-      searchptr->name_map = read_name_map (pfile,
-                                          !cstring_isEmpty (searchptr->fname)
-                                          ? searchptr->fname :
-                                          cstring_makeLiteralTemp ("."));
-      searchptr->got_name_map = 1;
-    }
-
-  /* First check the mapping for the directory we are using.  */
-
-  if ((searchptr != NULL)
-      && (searchptr->name_map != NULL))
-    {
-      from = filename;
-
-      if (!cstring_isEmpty (searchptr->fname))
-       {
-         from += cstring_length (searchptr->fname) + 1;
-       }
-
-      for (map = searchptr->name_map;
-          map != NULL;
-          map = map->map_next)
-       {
-         if (cstring_equal (map->map_from, cstring_fromChars (from)))
-           {
-             /*
-             ** Found a match.  Check if the file should be skipped
-             */
-             
-             if (cpp_skipIncludeFile (map->map_to))
-               {
-                 return SKIP_INCLUDE;
-               }
-             else
-               {
-                 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
-               }
-           }
-       }
-    }
-
-  /*
-  ** Try to find a mapping file for the particular directory we are
-  ** looking in.  Thus #include <sys/types.h> will look up sys/types.h
-  ** in /usr/include/header.gcc and look up types.h in
-  ** /usr/include/sys/header.gcc.
-  */
-
-  p = strrchr (filename, CONNECTCHAR);
-
-  if (p == NULL)
-    {
-      p = filename;
-    }
-
-  if ((searchptr != NULL)
-      && (cstring_isDefined (searchptr->fname))
-      && (cstring_length (searchptr->fname) == p - filename)
-      && !strncmp (cstring_toCharsSafe (searchptr->fname),
-                  filename,
-                  size_fromInt (p - filename)))
-    {
-      /* filename is in SEARCHPTR, which we've already checked.  */
-
-      if (cpp_skipIncludeFile (cstring_fromChars (filename)))
-       {
-         return SKIP_INCLUDE;
-       }
-      else
-       {
-         return cpp_openIncludeFile (filename);
-       }
-    }
-
-  if (p == filename)
-    {
-      dir = mstring_copy (".");
-      from = filename;
-    }
-  else
-    {
-      dir = (char *) dmalloc (size_fromInt (p - filename + 1));
-      memcpy (dir, filename, size_fromInt (p - filename));
-      dir[p - filename] = '\0';
-      from = p + 1;
-    }
-
-  for (map = read_name_map (pfile, cstring_fromChars (dir));
-       map != NULL;
-       map = map->map_next)
-    {
-      if (cstring_equal (map->map_from, cstring_fromChars (from)))
-       {
-         sfree (dir);
-
-         if (cpp_skipIncludeFile (map->map_to))
-           {
-             return SKIP_INCLUDE;
-           }
-         else
-           {
-             return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
-           }
-       }
-    }
-
-  sfree (dir);
-
-  if (cpp_skipIncludeFile (cstring_fromChars (filename)))
-    {
-      return SKIP_INCLUDE;
-    }
-  else
-    {
-      return cpp_openIncludeFile (filename);
-    }
-}
-
-/* Process the contents of include file FNAME, already open on descriptor F,
-   with output to OP.
-   SYSTEM_HEADER_P is 1 if this file resides in any one of the known
-   "system" include directories (as decided by the `is_system_include'
-   function above).
-   DIRPTR is the link in the dir path through which this file was found,
-   or 0 if the file name was absolute or via the current directory.
-   Return 1 on success, 0 on failure.
-
-   The caller is responsible for the cppReader_pushBuffer.  */
-
-static int
-finclude (cppReader *pfile, int f,
-         cstring fname,
-         bool system_header_p,
-         /*@dependent@*/ struct file_name_list *dirptr)
-{
-  mode_t st_mode;
-  size_t st_size;
-  long i;
-  int length = 0;
-  cppBuffer *fp;                       /* For input stack frame */
-
-  if (file_size_and_mode (f, &st_mode, &st_size) < 0)
-    {
-      cppReader_perrorWithName (pfile, fname);
-      check (close (f) == 0);
-      (void) cppReader_popBuffer (pfile);
-      /*@-mustfree@*/
-      return 0;
-      /*@=mustfree@*/
-    }
-
-  fp = cppReader_getBuffer (pfile);
-
-  /*@-temptrans@*/ /* fname shouldn't really be temp */
-  fp->nominal_fname = fp->fname = fname;
-  /*@=temptrans@*/
-
-  fp->dir = dirptr;
-  fp->system_header_p = system_header_p;
-  fp->lineno = 1;
-  fp->colno = 1;
-  fp->cleanup = cppReader_fileCleanup;
-
-  if (S_ISREG (st_mode))
-    {
-      sfree (fp->buf);
-      fp->buf = (char *) dmalloc (st_size + 2);
-      fp->alimit = fp->buf + st_size + 2;
-      fp->cur = fp->buf;
-
-      /* Read the file contents, knowing that st_size is an upper bound
-        on the number of bytes we can read.  */
-      length = safe_read (f, fp->buf, size_toInt (st_size));
-      fp->rlimit = fp->buf + length;
-      if (length < 0) goto nope;
-    }
-  else if (S_ISDIR (st_mode))
-    {
-      cppReader_error (pfile,
-                      message ("Directory specified in #include: %s", fname));
-      check (close (f) == 0);
-      return 0;
-    }
-  else
-    {
-      /*
-      ** Cannot count its file size before reading.
-      ** First read the entire file into heap and
-      ** copy them into buffer on stack.
-      */
-
-      size_t bsize = 2000;
-
-      st_size = 0;
-
-      sfree (fp->buf);
-      fp->buf = (char *) dmalloc (bsize + 2);
-
-      for (;;) {
-       i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));
-
-       if (i < 0)
-         goto nope;      /* error! */
-       st_size += i;
-
-       if (st_size != bsize)
-         {
-           break;      /* End of file */
-         }
-
-       bsize *= 2;
-       fp->buf = (char *) drealloc (fp->buf, bsize + 2);
-      }
-
-      fp->cur = fp->buf;
-      length = size_toInt (st_size);
-    }
-
-  if ((length > 0 && fp->buf[length - 1] != '\n')
-      /* Backslash-newline at end is not good enough.  */
-      || (length > 1 && fp->buf[length - 2] == '\\')) {
-    fp->buf[length++] = '\n';
-  }
-
-  fp->buf[length] = '\0';
-  fp->rlimit = fp->buf + length;
-
-  /* Close descriptor now, so nesting does not use lots of descriptors.  */
-  check (close (f) == 0);
-
-  /* Must do this before calling trigraph_pcp, so that the correct file name
-     will be printed in warning messages.  */
-
-  pfile->input_stack_listing_current = 0;
-  return 1;
-
- nope:
-
-  cppReader_perrorWithName (pfile, fname);
-  check (close (f) == 0);
-  sfree (fp->buf);
-  return 1;
-}
-
-void
-cppReader_init (cppReader *pfile)
-{
-  memset ((char *) pfile, 0, sizeof (*pfile));
-
-  pfile->get_token = cppGetToken;
-  pfile->token_buffer_size = 200;
-  pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
-  pfile->all_include_files = NULL;
-
-  assertSet (pfile);
-
-  cppReader_setWritten (pfile, 0);
-
-  pfile->system_include_depth = 0;
-  pfile->max_include_len = 0;
-  pfile->timebuf = NULL;
-  pfile->only_seen_white = 1;
-
-  pfile->buffer = cppReader_nullBuffer (pfile);
-}
-
-void
-cppReader_finish (/*@unused@*/ cppReader *pfile)
-{
-  ;
-}
-
-/* Free resources used by PFILE.
-   This is the cppReader 'finalizer' or 'destructor' (in C++ terminology).  */
-
-void
-cppCleanup (cppReader *pfile)
-{
-  while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
-    {
-      (void) cppReader_popBuffer (pfile);
-    }
-
-  if (pfile->token_buffer != NULL)
-    {
-      sfree (pfile->token_buffer);
-      pfile->token_buffer = NULL;
-    }
-
-  while (pfile->if_stack != NULL)
-    {
-      cppIfStackFrame *temp = pfile->if_stack;
-      pfile->if_stack = temp->next;
-      sfree (temp);
-    }
-
-  while (pfile->all_include_files != NULL)
-    {
-      struct file_name_list *temp = pfile->all_include_files;
-      pfile->all_include_files = temp->next;
-      /*@-dependenttrans@*/
-      cstring_free (temp->fname);
-      /*@=dependenttrans@*/
-      sfree (temp);
-    }
-
-  cppReader_hashCleanup ();
-}
-
-/*
-** Get the file-mode and data size of the file open on FD
-** and store them in *MODE_POINTER and *SIZE_POINTER.
-*/
-
-static int
-file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
-{
-  struct stat sbuf;
-
-  if (fstat (fd, &sbuf) < 0) {
-    return (-1);
-  }
-
-  if (mode_pointer != NULL)
-    {
-      *mode_pointer = sbuf.st_mode;
-    }
-
-  if (size_pointer != NULL)
-    {
-      *size_pointer = (size_t) sbuf.st_size;
-    }
-
-  return 0;
-}
-
-/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
-   retrying if necessary.  Return a negative value if an error occurs,
-   otherwise return the actual number of bytes read,
-   which must be LEN unless end-of-file was reached.  */
-
-static int safe_read (int desc, char *ptr, int len)
-{
-  int left = len;
-
-  while (left > 0)
-    {
-# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
-         /*@-compdef@*/ /* ptr is an out parameter */
-      int nchars = _read (desc, ptr, (unsigned) left);
-         /*@=compdef@*/
-# else
-      ssize_t nchars = read (desc, ptr, size_fromInt (left));
-# endif
-
-      if (nchars < 0)
-       {
-#ifdef EINTR
-         if (errno == EINTR)
-           continue;
-#endif
-         return (int) nchars;
-       }
-
-      if (nchars == 0) {
-       break;
-      }
-
-      ptr += nchars;
-      left -= nchars;
-    }
-
-  return len - left;
-}
-
-/* Initialize PMARK to remember the current position of PFILE.  */
-
-void
-parseSetMark (struct parse_marker *pmark, cppReader *pfile)
-{
-  cppBuffer *pbuf = cppReader_getBuffer (pfile);
-
-  pmark->next = pbuf->marks;
-  /*@-temptrans@*/
-  pbuf->marks = pmark;
-  /*@=temptrans@*/
-
-  pmark->buf = pbuf;
-  pmark->position = pbuf->cur - pbuf->buf;
-}
-
-/* Cleanup PMARK - we no longer need it.  */
-
-void parseClearMark (struct parse_marker *pmark)
-{
-  struct parse_marker **pp = &pmark->buf->marks;
-
-  for (; ; pp = &(*pp)->next)
-    {
-      llassert (*pp != NULL);
-      if (*pp == pmark) break;
-    }
-
-  *pp = pmark->next;
-}
-
-/* Backup the current position of PFILE to that saved in PMARK.  */
-
-void
-parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
-{
-  cppBuffer *pbuf = cppReader_getBuffer (pfile);
-
-  if (pbuf != pmark->buf)
-    {
-      cpp_setLocation (pfile);
-      llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
-    }
-
-  llassert (pbuf->buf != NULL);
-  pbuf->cur = pbuf->buf + pmark->position;
-}
-
-/* Reset PMARK to point to the current position of PFILE.  (Same
-   as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster.  */
-
-void
-parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
-{
-  cppBuffer *pbuf = cppReader_getBuffer (pfile);
-
-  if (pbuf != pmark->buf)
-    {
-      cpp_setLocation (pfile);
-      llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
-    }
-
-  pmark->position = pbuf->cur - pbuf->buf;
-}
-
-void cppReader_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
-{
-  struct cppOptions *opts = CPPOPTIONS (pfile);
-  cstring xp;
-
-  /* The code looks at the defaults through this pointer, rather than through
-     the constant structure above.  This pointer gets changed if an environment
-     variable specifies other defaults.  */
-
-  struct default_include *include_defaults = include_defaults_array;
-
-  /* Add dirs from INCLUDEPATH_VAR after dirs from -I.  */
-  /* There seems to be confusion about what CPATH should do,
-     so for the moment it is not documented.  */
-  /* Some people say that CPATH should replace the standard include dirs,
-     but that seems pointless: it comes before them, so it overrides them
-     anyway.  */
-
-  xp = osd_getEnvironmentVariable (INCLUDEPATH_VAR);
-
-  if (cstring_isDefined (xp) && !opts->no_standard_includes)
-    {
-      path_include (pfile, cstring_toCharsSafe (xp));
-    }
-
-  /* Now that dollars_in_ident is known, initialize is_idchar.  */
-  initialize_char_syntax (opts);
-
-  /* CppReader_Install __LINE__, etc.  Must follow initialize_char_syntax
-     and option processing.  */
-
-  initialize_builtins (pfile);
-
-  /* Do standard #defines and assertions
-     that identify system and machine type.  */
-
-  if (!opts->inhibit_predefs) {
-    char *p = (char *) dmalloc (strlen (predefs) + 1);
-    strcpy (p, predefs);
-
-    while (*p)
-      {
-       char *q;
-
-       while (*p == ' ' || *p == '\t')
-         {
-           p++;
-         }
-
-       /* Handle -D options.  */
-       if (p[0] == '-' && p[1] == 'D')
-         {
-           q = &p[2];
-
-           while (*p && *p != ' ' && *p != '\t')
-             {
-               p++;
-             }
-
-           if (*p != 0)
-             {
-               *p++= 0;
-             }
-
-           if (opts->debug_output)
-             {
-               output_line_command (pfile, 0, same_file);
-             }
-
-           cppReader_define (pfile, q);
-
-           while (*p == ' ' || *p == '\t')
-             {
-               p++;
-             }
-         }
-       else
-         {
-           abort ();
-         }
-      }
-
-    sfree (p);
-  }
-
-  opts->done_initializing = 1;
-
-  { /* Read the appropriate environment variable and if it exists
-       replace include_defaults with the listed path.  */
-    char *epath = 0;
-#ifdef __CYGWIN32__
-  char *win32epath;
-  int win32_buf_size = 0; /* memory we need to allocate */
-#endif
-
-  if (opts->cplusplus)
-    {
-      epath = getenv ("CPLUS_INCLUDE_PATH");
-    }
-  else
-    {
-      epath = getenv ("C_INCLUDE_PATH");
-    }
-
-  /*
-  ** If the environment var for this language is set,
-  ** add to the default list of include directories.
-  */
-
-    if (epath != NULL) {
-      char *nstore = (char *) dmalloc (strlen (epath) + 2);
-      int num_dirs;
-      char *startp, *endp;
-
-#ifdef __CYGWIN32__
-      /* if we have a posix path list, convert to win32 path list */
-      if (cygwin32_posix_path_list_p (epath))
-        {
-          win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);
-          win32epath = (char *) dmalloc /*@i4@*/ (win32_buf_size);
-          cygwin32_posix_to_win32_path_list (epath, win32epath);
-          epath = win32epath;
-        }
-#endif
-      for (num_dirs = 1, startp = epath; *startp; startp++)
-       {
-         if (*startp == PATH_SEPARATOR)
-           num_dirs++;
-       }
-
-      /*@-sizeoftype@*/
-      include_defaults
-       = (struct default_include *) dmalloc ((num_dirs
-                                              * sizeof (struct default_include))
-                                             + sizeof (include_defaults_array));
-      /*@=sizeoftype@*/
-
-      startp = endp = epath;
-      num_dirs = 0;
-      while (1) {
-        /* Handle cases like c:/usr/lib:d:/gcc/lib */
-        if ((*endp == PATH_SEPARATOR) || *endp == 0)
-         {
-           strncpy (nstore, startp, size_fromInt (endp - startp));
-           if (endp == startp)
-             {
-               strcpy (nstore, ".");
-             }
-           else
-             {
-               nstore[endp-startp] = '\0';
-             }
-
-           include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);
-           include_defaults[num_dirs].cplusplus = opts->cplusplus;
-           include_defaults[num_dirs].cxx_aware = 1;
-           num_dirs++;
-
-           if (*endp == '\0')
-             {
-               break;
-             }
-           endp = startp = endp + 1;
-         }
-       else
-         {
-           endp++;
-         }
-      }
-      /* Put the usual defaults back in at the end.  */
-      memcpy ((char *) &include_defaults[num_dirs],
-             (char *) include_defaults_array,
-             sizeof (include_defaults_array));
-
-      sfree (nstore);
-      /*@-branchstate@*/ } /*@=branchstate@*/
-  }
-
-  cppReader_appendIncludeChain (pfile, opts->before_system,
-                               opts->last_before_system);
-  opts->first_system_include = opts->before_system;
-
-  /* Unless -fnostdinc,
-     tack on the standard include file dirs to the specified list */
-  if (!opts->no_standard_includes) {
-    struct default_include *p = include_defaults;
-    char *specd_prefix = opts->include_prefix;
-    char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
-    int default_len = 0;
-
-       /* Remove the `include' from /usr/local/lib/gcc.../include.  */
-       if (default_prefix != NULL) {
-    if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
-      default_len = strlen (default_prefix) - 7;
-      default_prefix[default_len] = 0;
-    }
-       }
-
-    /* Search "translated" versions of GNU directories.
-       These have /usr/local/lib/gcc... replaced by specd_prefix.  */
-    if (specd_prefix != 0 && default_len != 0)
-      for (p = include_defaults; p->fname != NULL; p++) {
-       /* Some standard dirs are only for C++.  */
-       if (!p->cplusplus
-           || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
-         /* Does this dir start with the prefix?  */
-         if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix,
-                       size_fromInt (default_len)))
-           {
-             /* Yes; change prefix and add to search list.  */
-             struct file_name_list *nlist
-               = (struct file_name_list *) dmalloc (sizeof (*nlist));
-             size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;
-             char *str = (char *) dmalloc (this_len + 1);
-             strcpy (str, specd_prefix);
-             strcat (str, cstring_toCharsSafe (p->fname) + default_len);
-
-             nlist->next = NULL;
-             nlist->fname = cstring_fromChars (str);
-             nlist->control_macro = 0;
-             nlist->c_system_include_path = !p->cxx_aware;
-             nlist->got_name_map = 0;
-
-             cppReader_addIncludeChain (pfile, nlist);
-             if (opts->first_system_include == 0)
-               {
-                 opts->first_system_include = nlist;
-               }
-           }
-       }
-      }
-
-    /* Search ordinary names for GNU include directories.  */
-
-    for (p = include_defaults; p->fname != NULL; p++)
-      {
-       /* Some standard dirs are only for C++.  */
-       if (!p->cplusplus
-           || (opts->cplusplus && !opts->no_standard_cplusplus_includes))
-         {
-           struct file_name_list *nlist
-             = (struct file_name_list *) dmalloc (sizeof (*nlist));
-           nlist->control_macro = 0;
-           nlist->c_system_include_path = !p->cxx_aware;
-           nlist->fname = p->fname;
-           nlist->got_name_map = 0;
-           nlist->next = NULL;
-
-           cppReader_addIncludeChain (pfile, nlist);
-
-           if (opts->first_system_include == 0)
-             {
-               opts->first_system_include = nlist;
-             }
-         }
-      }
-    sfree (default_prefix);
-  }
-
-  /* Tack the after_include chain at the end of the include chain.  */
-  cppReader_appendIncludeChain (pfile, opts->after_include,
-                               opts->last_after_include);
-
-  if (opts->first_system_include == 0)
-    {
-      opts->first_system_include = opts->after_include;
-    }
-
-  /* With -v, print the list of dirs to search.  */
-  if (opts->verbose) {
-    struct file_name_list *p;
-    fprintf (stderr, "#include \"...\" search starts here:\n");
-
-    for (p = opts->include; p != NULL; p = p->next) {
-      if (p == opts->first_bracket_include)
-       fprintf (stderr, "#include <...> search starts here:\n");
-
-      fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
-    }
-    fprintf (stderr, "End of search list.\n");
-  }
-}
-
-int cppReader_startProcess (cppReader *pfile, cstring fname)
-{
-  cppBuffer *fp;
-  int f;
-  struct cppOptions *opts = CPPOPTIONS (pfile);
-
-  fp = cppReader_pushBuffer (pfile, NULL, 0);
-
-  if (fp == NULL)
-    {
-      return 0;
-    }
-
-  if (opts->in_fname == NULL)
-    {
-      opts->in_fname = cstring_makeLiteralTemp ("");
-    }
-
-  fp->fname = opts->in_fname;
-  fp->nominal_fname = fp->fname;
-  fp->lineno = 0;
-
-  /* Copy the entire contents of the main input file into
-     the stacked input buffer previously allocated for it.  */
-
-  if (cstring_isEmpty (fname))
-    {
-      fname = cstring_makeLiteralTemp ("");
-      f = 0;
-    }
-  else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)
-    {
-      cppReader_error (pfile,
-                      message ("Error opening %s for reading: %s",
-                               fname, lldecodeerror (errno)));
-
-      return 0;
-    }
-  else
-    {
-      ;
-    }
-
-  if (finclude (pfile, f, fname, 0, NULL))
-    {
-      output_line_command (pfile, 0, same_file);
-    }
-
-  return 1;
-}
-
-static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)
-{
-  return pfile->buffer;
-}
-
-/*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
-{
-  llassert (pfile->buffer != NULL);
-  return pfile->buffer;
-}
-
-/*@exposed@*/ char *cppLineBase (cppBuffer *buf)
-{
-  llassert (buf->buf != NULL);
-  return (buf->buf + buf->line_base);
-}
-
-int cppBufPeek (cppBuffer *buf)
-{
-  if (buf->cur == NULL || buf->rlimit == NULL) {
-    return EOF;
-  }
-
-  if (buf->cur < buf->rlimit) {
-    return *(buf->cur);
-  }
-
-  return EOF;
-}
-
-bool cppBuffer_isMacro (cppBuffer *buf)
-{
-  if (buf != NULL)
-    {
-      return (buf->cleanup == cppReader_macroCleanup);
-    }
-
-  return FALSE;
-}
-
-/*
-** Returns true if the macro should be checked, false
-** if it should be expanded normally.
-*/
-
-static bool notparseable = FALSE;  /* preceeded by @notparseable@ */
-static bool notfunction = FALSE;   /* preceeded by @notfunction@ */
-static bool expectiter = FALSE;    /* preceeded by @iter@ */
-static bool expectenditer = FALSE; /* second after @iter@ */
-static bool expectfunction = FALSE;    /* preceeded by @function@ */
-static bool expectconstant = FALSE;   /* preceeded by @constant@ */
-static bool expectmacro = FALSE;   /* preceeded by notfunction or notparseable */
-
-static void cpp_setLocation (cppReader *pfile)
-{
-  fileId fid;
-  int line;
-
-  if (pfile->buffer != NULL)
-    {
-      if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname))
-       {
-         cstring fname = cppReader_getBuffer (pfile)->nominal_fname;
-         
-         DPRINTF (("Looking up: %s", fname));
-         
-         if (fileTable_exists (context_fileTable (), fname))
-           {
-             fid = fileTable_lookup (context_fileTable (), fname);
-           }
-         else
-           {
-             DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
-
-             fid = fileTable_lookup (context_fileTable (),
-                                     cppReader_getBuffer (pfile)->fname);
-           }
-       }
-      else
-       {
-         fid = fileTable_lookup (context_fileTable (),
-                                 cppReader_getBuffer (pfile)->fname);
-       }
-      
-      line = cppReader_getBuffer (pfile)->lineno;
-      fileloc_free (g_currentloc);
-
-      if (fileId_isValid (fid))
-       {
-         g_currentloc = fileloc_create (fid, line, 1);
-       }
-      else
-       {
-         g_currentloc = fileloc_createBuiltin ();
-       }
-    }
-  else
-    {
-      fileloc_free (g_currentloc);
-      g_currentloc = fileloc_createBuiltin ();
-    }
-}
-
-static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/
-{
-  bool checkmacro = FALSE;
-  bool hasParams = FALSE;
-  bool noexpand = FALSE;
-  cstring sname;
-  char c;
-
-  cpp_setLocation (pfile);
-
-  DPRINTF (("Should check macro? %s", p));
-
-  if (expectiter || expectconstant || expectenditer)
-    {
-      if (expectiter)
-       {
-         expectiter = FALSE;
-         expectenditer = TRUE;
-       }
-      else
-       {
-         expectiter = FALSE;
-         expectconstant = FALSE;
-         expectenditer = FALSE;
-       }
-
-      if (notfunction || notparseable)
-       {
-         notfunction = FALSE;
-         notparseable = FALSE;
-         return FALSE;
-       }
-      else
-       {
-         return TRUE;
-       }
-    }
-
-  llassert (*p == '#');
-  p++;
-
-  while (*p == ' ' || *p == '\t')
-    {
-      p++;
-    }
-
-  llassert (*p == 'd'); /* define starts */
-
-  p += 6;
-
-  while (*p == ' ' || *p == '\t')
-    {
-      p++;
-    }
-
-  sname = cstring_fromChars (p);
-  DPRINTF (("Check macro: %s", sname));
-
-  while (((c = *p) != ' ')
-        && c != '\0' && c != '('
-        && c != '\t' && c != '\\' && c != '\n'
-        && !iscntrl (c))
-    {
-      p++;
-    }
-
-  hasParams = (c == '(');
-  *p = '\0';
-
-
-  if (notparseable)
-    {
-      notparseable = FALSE;
-    }
-  else if (notfunction || fileloc_isStandardLib (g_currentloc))
-    {
-      DPRINTF (("Clear notfunction"));
-      notfunction = FALSE;
-    }
-  else
-    {
-      if (noexpand)
-       {
-         checkmacro = TRUE;
-
-         if (!expectenditer)
-           {
-             noexpand = FALSE;
-           }
-       }
-      else
-       {
-         if (usymtab_existsReal (sname))
-           {
-             uentry ue = usymtab_lookup (sname);
-
-             DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
-
-             if (fileloc_isPreproc (uentry_whereLast (ue)))
-               {
-                 goto macroDne;
-               }
-             else
-               {
-                 if (uentry_isSpecified (ue))
-                   {
-                     checkmacro = context_getFlag (FLG_SPECMACROS);
-                   }
-                 else
-                   {
-                     if (hasParams)
-                       {
-                         checkmacro = context_getFlag (FLG_LIBMACROS)
-                           || context_getFlag (FLG_FCNMACROS);
-                       }
-                   }
-               }
-           }
-         else
-           {
-           macroDne:
-             DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));
-
-             if (fileloc_isSystemFile (g_currentloc)
-                 && context_getFlag (FLG_SYSTEMDIREXPAND))
-               {
-                 ; /* don't check this macro */
-                 DPRINTF (("Don't check 1"));
-               }
-             else
-               {
-                 uentry le;
-                 
-                 if (hasParams)
-                   {
-                     DPRINTF (("Has params..."));
-
-                     if (context_getFlag (FLG_FCNMACROS))
-                       {
-                         if (usymtab_exists (sname))
-                           {
-                              /*
-                             ** only get here is macro is redefined
-                             ** error reported elsewhere
-                             */
-
-                             DPRINTF (("It exists!"));
-                           }
-                         else
-                           {
-                             /*
-                             ** We make it a forward function, since it might be declared elsewhere.
-                             ** After all headers have been processed, we should check the forward
-                             ** functions.
-                             */
-
-                             fileloc loc = fileloc_makePreproc (g_currentloc);
-
-                             /* the line is off-by-one, since the newline was already read */
-                             decLine ();
-
-                             if (expectfunction)
-                               {
-                                 expectfunction = FALSE;
-                               }
-
-                             le = uentry_makeForwardFunction (sname,
-                                                              typeId_invalid, loc);
-
-                             fileloc_free (loc);
-
-                             incLine ();
-
-                             /* Do not define here! */
-
-                             (void) usymtab_addEntry (le);
-                           }
-
-                         checkmacro = TRUE;
-                         DPRINTF (("Check: TRUE"));
-                       }
-                     else 
-                       {
-                         DPRINTF (("Flag FCN_MACROS not set!"));
-                       }
-                   }
-                 else
-                   {
-                     DPRINTF (("No params"));
-
-                     if (context_getFlag (FLG_CONSTMACROS))
-                       {
-                         bool nocontent = FALSE;
-
-                         if (c == '\0')
-                           {
-                             nocontent = TRUE;
-                           }
-                         else
-                           {
-                             if (isspace (c))
-                               {
-                                 char *rest = p + 1;
-
-                                 /*
-                                 ** Check if there is nothing after the define.
-                                 */
-
-                                 while ((*rest) != '\0' && isspace (*rest))
-                                   {
-                                     rest++;
-                                   }
-
-                                 if (*rest == '\0')
-                                   {
-                                     nocontent = TRUE; /* empty macro, don't check */
-                                   }
-                               }
-                           }
-
-                         if (usymtab_exists (sname))
-                           {
-                             ;
-                           }
-                         else
-                           {
-                             fileloc loc = fileloc_makePreproc (g_currentloc);
-                             DPRINTF (("Make constant: %s", sname));
-                             le = uentry_makeConstant (sname,
-                                                       ctype_unknown, loc);
-                             (void) usymtab_addEntry (le);
-                           }
-
-                         checkmacro = !nocontent;
-                       }
-                   }
-               }
-
-             if (checkmacro && usymtab_existsType (sname))
-               {
-                 DPRINTF (("Making false..."));
-                 decLine ();
-                 ppllerror (message ("Specified type implemented as macro: %s", sname));
-                 checkmacro = FALSE;
-                 incLine ();
-               }
-           }
-       }
-    }
-
-  if (!checkmacro)
-    {
-      if (usymtab_exists (sname))
-       {
-         uentry ue = usymtab_lookupExpose (sname);
-         fileloc tloc = fileloc_makePreproc (g_currentloc);
-
-         uentry_setDefined (ue, tloc);
-         fileloc_free (tloc);
-         uentry_setUsed (ue, fileloc_undefined);
-       }
-      else
-       {
-         fileloc tloc = fileloc_makePreproc (g_currentloc);
-         uentry ue = uentry_makeExpandedMacro (sname, tloc);
-         DPRINTF (("Make expanded macro: %s", sname));
-         DPRINTF (("Not in symbol table: %s", sname));
-         
-         (void) usymtab_addGlobalEntry (ue);
-         fileloc_free (tloc);
-       }
-    }
-
-  *p = c;
-  DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
-  return checkmacro;
-}
-
-static enum cpp_token
-cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
-{
-  cppBuffer *pbuf = cppReader_getBuffer (pfile);
-  char *start;
-  int len;
-  bool eliminateComment = FALSE;
-
-  llassert (pbuf->buf != NULL);
-
-  start = pbuf->buf + smark->position;
-
-  llassert (pbuf->cur != NULL);
-  len = pbuf->cur - start;
-
-  if (start[0] == '*'
-      && start[1] == context_getCommentMarkerChar ())
-    {
-      int i;
-      char c = ' ';
-      char *scomment = start + 2;
-      char savec = start[len];
-
-      start[0] = BEFORE_COMMENT_MARKER[0];
-      start[1] = BEFORE_COMMENT_MARKER[1];
-
-      llassert (start[len - 2] == '*');
-      start[len - 2] = AFTER_COMMENT_MARKER[0];
-
-      llassert (start[len - 1] == '/');
-      start[len - 1] = AFTER_COMMENT_MARKER[1];
-
-      cppReader_reserve(pfile, size_fromInt (1 + len));
-      cppReader_putCharQ (pfile, c);
-
-      cpp_setLocation (pfile);
-
-      start[len] = '\0';
-
-      if (mstring_containsString (scomment, "/*"))
-       {
-         (void) cppoptgenerror 
-           (FLG_NESTCOMMENT,
-            message ("Comment starts inside syntactic comment: %s", 
-                     cstring_fromChars (scomment)),
-            pfile);
-       }
-
-      start[len] = savec;
-
-      if (mstring_equalPrefix (scomment, "ignore"))
-       {
-         if (!context_getFlag (FLG_NOCOMMENTS))
-           {
-             context_enterSuppressRegion ();
-           }
-       }
-      else if (mstring_equalPrefix (scomment, "end"))
-       {
-         if (!context_getFlag (FLG_NOCOMMENTS))
-           {
-             context_exitSuppressRegion ();
-           }
-       }
-      else if (mstring_equalPrefix (scomment, "notparseable"))
-       {
-         notparseable = TRUE;
-         expectmacro = TRUE;
-         eliminateComment = TRUE;
-       }
-      else if (mstring_equalPrefix (scomment, "notfunction"))
-       {
-         notfunction = TRUE;
-         expectmacro = TRUE;
-         eliminateComment = TRUE;
-       }
-      else if (mstring_equalPrefix (scomment, "iter"))
-       {
-         expectiter = TRUE;
-       }
-      else if (mstring_equalPrefix (scomment, "function"))
-       {
-         expectfunction = TRUE;
-       }
-      else if (mstring_equalPrefix (scomment, "constant"))
-       {
-         expectconstant = TRUE;
-       }
-      else
-       {
-         char sChar = *scomment;
-
-         if (sChar == '='
-             || sChar == '-'
-             || sChar == '+')
-           {
-             char *rest = scomment + 1;
-
-             if (mstring_equalPrefix (rest, "commentchar"))
-               {
-                 eliminateComment = TRUE;
-
-                 if (sChar == '=')
-                   {
-                     ppllerror (cstring_makeLiteral
-                                ("Cannot restore commentchar"));
-                   }
-                 else
-                   {
-                     char *next = scomment + 12; /* strlen commentchar = 12 */
-
-                     if (*next != ' ' && *next != '\t' && *next != '\n')
-                       {
-                         ppllerror
-                           (message
-                            ("Syntactic commentchar comment is not followed by a "
-                             "whitespace character: %c",
-                             *next));
-                       }
-                     else
-                       {
-                         char cchar = *(next + 1);
-
-                         if (cchar == '\0')
-                           {
-                             ppllerror
-                               (cstring_makeLiteral
-                                ("Cannot set commentchar to NUL"));
-                           }
-                         else
-                           {
-                             context_setCommentMarkerChar (cchar);
-                             /* setComment = TRUE; */
-                           }
-                       }
-                   }
-               }
-             else if (mstring_equalPrefix (scomment, "nestcomment"))
-               {
-                 /* fix from Mike Miller <MikeM@xata.com> */
-                 context_fileSetFlag (FLG_NESTCOMMENT,
-                                      ynm_fromCodeChar (sChar));
-               }
-             else if (mstring_equalPrefix (rest, "namechecks"))
-               {
-                 context_fileSetFlag (FLG_NAMECHECKS,
-                                      ynm_fromCodeChar (sChar));
-               }
-             else if (mstring_equalPrefix (rest, "macroredef"))
-               {
-                 context_fileSetFlag (FLG_MACROREDEF,
-                                      ynm_fromCodeChar (sChar));
-               }
-             else if (mstring_equalPrefix (rest, "usevarargs"))
-               {
-                 context_fileSetFlag (FLG_USEVARARGS,
-                                      ynm_fromCodeChar (sChar));
-               }
-             else if (mstring_equalPrefix (rest, "nextlinemacros"))
-               {
-                 context_fileSetFlag (FLG_MACRONEXTLINE,
-                                      ynm_fromCodeChar (sChar));
-               }
-             else if (mstring_equalPrefix (rest, "allmacros")
-                      || mstring_equalPrefix (rest, "fcnmacros")
-                      || mstring_equalPrefix (rest, "constmacros"))
-               {
-                 flagcode fl;
-
-                 if (mstring_equalPrefix (rest, "allmacros"))
-                   {
-                     fl = FLG_ALLMACROS;
-                   }
-                 else if (mstring_equalPrefix (rest, "fcnmacros"))
-                   {
-                     fl = FLG_FCNMACROS;
-                   }
-                 else
-                   {
-                     llassert (mstring_equalPrefix (rest, "constmacros"));
-                     fl = FLG_CONSTMACROS;
-                   }
-
-
-                 context_fileSetFlag (fl, ynm_fromCodeChar (sChar));
-                 notfunction = FALSE;
-               }
-             else
-               {
-                 ;
-               }
-           }
-         else
-           {
-             ;
-           }
-       }
-
-      if (eliminateComment)
-       {
-         goto removeComment;
-       }
-
-      /* Replaces comment char's in start with spaces */
-
-      for (i = 2; i < len - 2; i++)
-       {
-         if (start[i] == BEFORE_COMMENT_MARKER[0]
-             || start[i] == BEFORE_COMMENT_MARKER[1]
-             || start[i] == context_getCommentMarkerChar ())
-           {
-             start[i] = ' ';
-           }
-       }
-
-      cppReader_putStrN (pfile, start, size_fromInt (len));
-      parseClearMark (smark);
-      return CPP_COMMENT;
-    }
-  else
-    {
-    removeComment:
-      {
-       int i;
-
-       /*
-       ** Output the comment as all spaces so line/column
-       ** in output file is still correct.
-       */
-
-       char c = ' ';
-       cstring lintcomment = cstring_undefined;
-
-       if (context_getFlag (FLG_LINTCOMMENTS))
-         {
-           if (mstring_equalPrefix (start, "*NOTREACHED*/"))
-             {
-               lintcomment = cstring_makeLiteralTemp ("l_notreach");
-             }
-           else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
-             {
-               lintcomment = cstring_makeLiteralTemp ("l_printfli");
-             }
-           else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
-             {
-               lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
-             }
-           else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
-             {
-               lintcomment = cstring_makeLiteralTemp ("l_argsus");
-             }
-           else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
-             {
-               lintcomment = cstring_makeLiteralTemp ("l_fallth");
-             }
-           else
-             {
-               lintcomment = cstring_undefined;
-             }
-         }
-       else
-         {
-           lintcomment = cstring_undefined;
-         }
-
-       if (cstring_isDefined (lintcomment))
-         {
-           c = BEFORE_COMMENT_MARKER[0];
-           start[0] = BEFORE_COMMENT_MARKER[1];
-
-           llassert (cstring_length (lintcomment) == len - 3);
-
-           for (i = 1; i < len - 2; i++)
-             {
-               start[i] = cstring_getChar (lintcomment, i);
-             }
-           
-           start[len - 2] = AFTER_COMMENT_MARKER[0];
-           start[len - 1] = AFTER_COMMENT_MARKER[1];
-         }
-       else
-         {
-           /* Replaces  char's in start with spaces */
-           for (i = 0; i < len; i++)
-             {
-               if (start[i] == '/'
-                   && i < len - 1
-                   && start[i + 1] == '*') {
-                 (void) cppoptgenerror (FLG_NESTCOMMENT,
-                                        message ("Comment starts inside comment"),
-                                        pfile);
-               }
-               
-               if (start[i] != '\n')
-                 {
-                   start[i] = ' ';
-                 }
-             }
-         }
-
-       cppReader_reserve (pfile, size_fromInt (1 + len));
-       cppReader_putCharQ (pfile, c);
-       cppReader_putStrN (pfile, start, size_fromInt (len));
-       parseClearMark (smark);
-       return CPP_COMMENT;
-      }
-    }
-}
-
-static int cpp_openIncludeFile (char *filename)
-{
-  int res = open (filename, O_RDONLY, 0666);
-
-  /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
-  if (res >= 0)
-    {
-      if (!fileTable_exists (context_fileTable (),
-                            cstring_fromChars (filename)))
-       {
-         (void) fileTable_addHeaderFile (context_fileTable (),
-                                         cstring_fromChars (filename));
-       }
-      else
-       {
-         DPRINTF (("File already exists: %s", filename));
-       }
-    }
-
-  return res;
-}
-
-static bool cpp_skipIncludeFile (cstring fname)
-{
-  if (context_isSystemDir (fname))
-    {
-      DPRINTF (("System dir: %s", fname));
-
-      if (lcllib_isSkipHeader (fname))
-       {
-         DPRINTF (("Skip include TRUE: %s", fname));
-         return TRUE;
-       }
-      
-      if (context_getFlag (FLG_SKIPSYSHEADERS))
-       {
-         DPRINTF (("Skip include TRUE: %s", fname));
-         return TRUE;
-       }
-    }
-
-  if (context_getFlag (FLG_SINGLEINCLUDE))
-    {
-      fname = removePreDirs (fname);
-
-# if defined (WIN32) || defined (OS2)
-      cstring_replaceAll (fname, '/', '\\');
-# endif
-
-      if (fileTable_exists (context_fileTable (), fname))
-       {
-         DPRINTF (("Skip include TRUE: %s", fname));
-         return TRUE;
-       }
-    }
-
-  DPRINTF (("Skip include FALSE: %s", fname));
-  return FALSE;
-}
-
-static int cpp_peekN (cppReader *pfile, int n)
-{
-  cppBuffer *buf = cppReader_getBuffer (pfile);
-
-  llassert (buf->cur != NULL);
-
-  return (buf->rlimit - buf->cur >= (n)
-         ? buf->cur[n]
-         : EOF);
-}
-
-cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
-{
-  return buf + 1;
-}
-
-void cppBuffer_forward (cppBuffer *buf, int n)
-{
-  llassert (buf->cur != NULL);
-  buf->cur += n;
-}
+/*\r
+See\r
+http://src.openresources.com/debian/src/devel/HTML/S/altgcc_2.7.2.2.orig%20altgcc-2.7.2.2.orig%20protoize.c.html\r
+static char *\r
+abspath (cwd, rel_filename)\r
+\r
+*/\r
+\r
+/*!!!!\r
+*** cpplib.c.old Tue Nov 28 2000 09:04:09 AM\r
+--- cpplib.c Tue Nov 28 2000 08:55:18 AM\r
+***************\r
+*** 5715,5722 ****\r
+     c2 = cppReader_peekC (pfile)\r
+     if (c2 != '\n'\r
+       goto randomchar\r
+!    token = CPP_HSPACE\r
+!    goto op2any\r
+--- 5714,5723 ----\r
+          case '\\'\r
+     c2 = cppReader_peekC (pfile)\r
+     if (c2 != '\n'\r
+       goto randomchar\r
+!    cppReader_forward (pfile, 1)\r
+!    pfile->lineno++\r
+!    return CPP_HSPACE\r
+  \r
\r
+   case '\n'\r
+     cppReader_putChar (pfile, c)\r
+\r
+\r
+Carl J. Appellof ( mailto:cappello@legato.com <mailto:cappello@legato.com> )\r
+*/ /*@i8@*/\r
+\r
+/*\r
+** LCLint - annotation-assisted static program checker\r
+** Copyright (C) 1994-2001 University of Virginia,\r
+**         Massachusetts Institute of Technology\r
+**\r
+** This program is free software; you can redistribute it and/or modify it\r
+** under the terms of the GNU General Public License as published by the\r
+** Free Software Foundation; either version 2 of the License, or (at your\r
+** option) any later version.\r
+** \r
+** This program is distributed in the hope that it will be useful, but\r
+** WITHOUT ANY WARRANTY; without even the implied warranty of\r
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+** General Public License for more details.\r
+** \r
+** The GNU General Public License is available from http://www.gnu.org/ or\r
+** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,\r
+** MA 02111-1307, USA.\r
+**\r
+** For information on lclint: lclint-request@cs.virginia.edu\r
+** To report a bug: lclint-bug@cs.virginia.edu\r
+** For more information: http://lclint.cs.virginia.edu\r
+*/\r
+/*\r
+** cpplib.c\r
+*/\r
+/*\r
+   Copyright (C) 1986, 87, 89, 92-6, 1997 Free Software Foundation, Inc.\r
+   Contributed by Per Bothner, 1994-95.\r
+   Based on CCCP program by Paul Rubin, June 1986\r
+   Adapted to ANSI C, Richard Stallman, Jan 1987\r
+\r
+This program is free software; you can redistribute it and/or modify it\r
+under the terms of the GNU General Public License as published by the\r
+Free Software Foundation; either version 2, or (at your option) any\r
+later version.\r
+\r
+This program is distributed in the hope that it will be useful,\r
+but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+GNU General Public License for more details.\r
+\r
+You should have received a copy of the GNU General Public License\r
+along with this program; if not, write to the Free Software\r
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+\r
+ In other words, you are welcome to use, share and improve this program.\r
+ You are forbidden to forbid anyone else to use, share and improve\r
+ what you give them.   Help stamp out software-hoarding!  */\r
+\r
+/*\r
+ * Herbert 06/12/2000:\r
+ * - OS2 drive specs like WIN32\r
+ * - Includes for IBMs OS/2 compiler\r
+ */\r
+\r
+# include <ctype.h>\r
+# include <stdio.h>\r
+# include <signal.h>\r
+# ifdef __STDC__\r
+# include <stdlib.h>\r
+# endif\r
+\r
+# include <string.h>\r
+\r
+# if !(defined (WIN32) || defined (OS2) && defined (__IBMC__))\r
+# include <unistd.h>\r
+# endif\r
+\r
+# include <sys/types.h>\r
+# include <sys/stat.h>\r
+# include <fcntl.h>\r
+\r
+# if defined (WIN32) || defined (OS2) && defined (__IBMC__)\r
+# include <io.h>\r
+# include <sys/utime.h>                /* for __DATE__ and __TIME__ */\r
+# include <time.h>\r
+# else\r
+# ifndef VMS\r
+# ifndef USG\r
+# include <time.h> /* Reported by Paul Smith */\r
+# include <sys/time.h>\r
+# include <sys/resource.h>\r
+# else\r
+# include <sys/times.h>\r
+# include <time.h>\r
+# include <fcntl.h>\r
+# endif /* USG */\r
+# endif /* not VMS */\r
+# endif /* not WIN32 */\r
+\r
+/* This defines "errno" properly for VMS, and gives us EACCES.  */\r
+# include <errno.h>\r
+\r
+# include "lclintMacros.nf"\r
+# include "llbasic.h"\r
+# include "lcllib.h"\r
+# include "cpplib.h"\r
+# include "cpperror.h"\r
+# include "cpphash.h"\r
+# include "cppexp.h"\r
+# include "version.h"\r
+# include "portab.h"\r
+# include "osd.h"\r
+\r
+/*\r
+** This is really kludgey code...\r
+*/\r
+\r
+/*@+boolint@*/\r
+/*@+charint@*/\r
+\r
+#define NO_SHORTNAMES\r
+\r
+# ifdef open\r
+# undef open\r
+# undef read\r
+# undef write\r
+# endif /* open */\r
+\r
+/*@constant int IMPORT_FOUND@*/\r
+# define IMPORT_FOUND -2\r
+\r
+/*@constant int SKIP_INCLUDE@*/\r
+# define SKIP_INCLUDE IMPORT_FOUND\r
+\r
+/*@constant unused int IMPORT_NOT_FOUND@*/\r
+# define IMPORT_NOT_FOUND -1\r
+\r
+#ifndef STDC_VALUE\r
+/*@constant unused int STDC_VALUE@*/\r
+#define STDC_VALUE 1\r
+#endif\r
+\r
+/* By default, colon separates directories in a path.  */\r
+#ifndef PATH_SEPARATOR\r
+/*@constant char PATH_SEPARATOR@*/\r
+#define PATH_SEPARATOR ':'\r
+#endif\r
+\r
+static void parse_name (cppReader *, int);\r
+\r
+static int cpp_openIncludeFile (char *p_filename)\r
+     /*@modifies fileSystem @*/ ;\r
+\r
+static void cpp_setLocation (cppReader *p_pfile)\r
+     /*@modifies g_currentloc@*/ ;\r
+\r
+static enum cpp_token cpp_handleComment (cppReader *p_pfile,\r
+                                        struct parse_marker *p_smark)\r
+     /*@modifies p_pfile, p_smark@*/;\r
+\r
+static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@*/ ;\r
+\r
+static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ;\r
+\r
+#ifndef O_RDONLY\r
+#define O_RDONLY 0\r
+#endif\r
+\r
+/* Symbols to predefine.  */\r
+\r
+#ifdef CPP_PREDEFINES\r
+static /*@observer@*/ char *predefs = CPP_PREDEFINES;\r
+#else\r
+static /*@observer@*/ char *predefs = "";\r
+#endif\r
+\r
+/* We let tm.h override the types used here, to handle trivial differences\r
+   such as the choice of unsigned int or long unsigned int for size_t.\r
+   When machines start needing nontrivial differences in the size type,\r
+   it would be best to do something here to figure out automatically\r
+   from other information what type to use.  */\r
+\r
+/* The string value for __SIZE_TYPE__.  */\r
+\r
+#ifndef SIZE_TYPE\r
+/*@constant observer char *SIZE_TYPE@*/\r
+#define SIZE_TYPE "long unsigned int"\r
+#endif\r
+\r
+/* The string value for __PTRDIFF_TYPE__.  */\r
+\r
+#ifndef PTRDIFF_TYPE\r
+/*@constant observer char *PTRDIFF_TYPE@*/\r
+#define PTRDIFF_TYPE "long int"\r
+#endif\r
+\r
+/* The string value for __WCHAR_TYPE__.  */\r
+\r
+#ifndef WCHAR_TYPE\r
+/*@constant observer char *WCHAR_TYPE@*/\r
+#define WCHAR_TYPE "int"\r
+#endif\r
+\r
+/* The string value for __USER_LABEL_PREFIX__ */\r
+\r
+#ifndef USER_LABEL_PREFIX\r
+/*@constant observer char *USER_LABEL_PREFIX@*/\r
+#define USER_LABEL_PREFIX ""\r
+#endif\r
+\r
+/* The string value for __REGISTER_PREFIX__ */\r
+\r
+#ifndef REGISTER_PREFIX\r
+/*@constant observer char *REGISTER_PREFIX@*/\r
+#define REGISTER_PREFIX ""\r
+#endif\r
+\r
+/* table to tell if char can be part of a C identifier.  */\r
+static bool is_idchar[256];\r
+/* table to tell if char can be first char of a c identifier.  */\r
+static bool is_idstart[256];\r
+/* table to tell if c is horizontal space.  */\r
+static bool is_hor_space[256];\r
+/* table to tell if c is horizontal or vertical space.  */\r
+static bool is_space[256];\r
+\r
+static /*@exposed@*/ /*@null@*/ cppBuffer *\r
+cppReader_getBuffer (/*@special@*/ cppReader *p_pfile)\r
+     /*@uses p_pfile->buffer@*/\r
+     /*@modifies nothing@*/ ;\r
+\r
+/*@notfunction@*/\r
+# define SKIP_WHITE_SPACE(p) do { /*@access cstring@*/ while (is_hor_space[(int) *(p)]) { (p)++; } } /*@noaccess cstring@*/ while (0)\r
+\r
+/*@notfunction@*/\r
+# define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*(p)]) { (p)++; } } while (0)\r
+\r
+static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ;\r
+\r
+/*@function static int cppBuffer_get (sef cppBuffer *p_b) modifies *p_b ; @*/\r
+# define cppBuffer_get(BUFFER) \\r
+  ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)\r
+\r
+/* Append string STR (of length N) to PFILE's output buffer.  Make space. */\r
+/*@function static void cppReader_puts (sef cppReader *p_file, char *p_str, sef size_t p_n)\r
+                     modifies *p_file; @*/\r
+# define cppReader_puts(PFILE, STR, N) \\r
+  cppReader_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N)\r
+\r
+/* Append character CH to PFILE's output buffer.  Assume sufficient space. */\r
+\r
+/*@function static void cppReader_putCharQ (cppReader *p_file, char p_ch)\r
+                    modifies *p_file; @*/\r
+# define cppReader_putCharQ(PFILE, CH) (*(PFILE)->limit++ = (CH))\r
+\r
+/* Append character CH to PFILE's output buffer.  Make space if need be. */\r
+\r
+/*@function static void cppReader_putChar (sef cppReader *p_file, char p_ch)\r
+                    modifies *p_file; @*/\r
+#define cppReader_putChar(PFILE, CH) (cppReader_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH))\r
+\r
+/* Make sure PFILE->limit is followed by '\0'. */\r
+/*@function static void cppReader_nullTerminateQ (cppReader *p_file)\r
+      modifies *p_file; @*/\r
+\r
+#define cppReader_nullTerminateQ(PFILE) (*(PFILE)->limit = 0)\r
+\r
+/*@function static void cppReader_nullTerminate (sef cppReader *p_file)\r
+                           modifies *p_file; @*/\r
+# define cppReader_nullTerminate(PFILE) \\r
+  (cppReader_reserve (PFILE, (size_t) 1), *(PFILE)->limit = 0)\r
+\r
+/*@function static void cppReader_adjustWritten (cppReader *p_file, size_t)\r
+                           modifies *p_file; @*/\r
+#define cppReader_adjustWritten(PFILE,DELTA) ((PFILE)->limit += (DELTA))\r
+\r
+/*@function static bool cppReader_isC89 (cppReader *) modifies nothing; @*/\r
+#define cppReader_isC89(PFILE) (CPPOPTIONS(PFILE)->c89)\r
+\r
+/*@function static observer char *cppReader_wcharType (cppReader *)\r
+     modifies nothing; @*/\r
+\r
+# define cppReader_wcharType(PFILE) \\r
+  (CPPOPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE)\r
+\r
+static void cppBuffer_forward (cppBuffer *p_buf, int p_n) /*@modifies *p_buf@*/ ;\r
+\r
+/*@function static void cppReader_forward (cppReader *p_pfile, int) modifies *p_pfile; @*/\r
+# define cppReader_forward(pfile, N) \\r
+  (cppBuffer_forward (cppReader_getBufferSafe (pfile), (N)))\r
+\r
+/*@function static int cppReader_getC (cppReader *p_pfile) modifies *p_pfile; @*/\r
+# define cppReader_getC(pfile)   (cppBuffer_get (cppReader_getBufferSafe (pfile)))\r
+\r
+/*@function static int cppReader_peekC (cppReader *) modifies nothing;@*/\r
+# define cppReader_peekC(pfile)  (cppBufPeek (cppReader_getBufferSafe (pfile)))\r
+\r
+/* Move all backslash-newline pairs out of embarrassing places.\r
+   Exchange all such pairs following BP\r
+   with any potentially-embarrassing characters that follow them.\r
+   Potentially-embarrassing characters are / and *\r
+   (because a backslash-newline inside a comment delimiter\r
+   would cause it not to be recognized).  */\r
+\r
+/*@notfunction@*/\r
+# define NEWLINE_FIX \\r
+   do { while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n') { cppReader_forward (pfile, 2); } } while(FALSE)\r
+\r
+     /* Same, but assume we've already read the potential '\\' into C.  */\r
+/*@notfunction@*/\r
+# define NEWLINE_FIX1(C) do { \\r
+     while ((C) == '\\' && cppReader_peekC (pfile) == '\n') { cppReader_forward (pfile, 1); (C) = cppReader_getC (pfile); }\\r
+                                                                          } while(0)\r
+\r
+static void parseSetMark (/*@out@*/ struct parse_marker *,\r
+                         cppReader *);\r
+static void parseClearMark (struct parse_marker *);\r
+static void parseGotoMark (struct parse_marker *, cppReader *);\r
+static void parseMoveMark (struct parse_marker *, cppReader *);\r
+\r
+/* If we have a huge buffer, may need to cache more recent counts */\r
+static /*@exposed@*/ char *cppLineBase (/*@sef@*/ cppBuffer *);\r
+\r
+static /*@exposed@*/ /*@null@*/ cppBuffer *\r
+   cppReader_pushBuffer (cppReader *p_pfile,\r
+                        /*@owned@*/ /*@null@*/ char *, size_t)\r
+     /*@modifies p_pfile@*/ ;\r
+\r
+static void cppReader_appendIncludeChain\r
+(cppReader *p_pfile,\r
+ /*@keep@*/ struct file_name_list *p_first,\r
+ /*@dependent@*/ struct file_name_list *p_last);\r
+\r
+static void cppReader_macroCleanup (cppBuffer *p_pbuf, cppReader *p_pfile);\r
+static enum cpp_token cppReader_nullUnderflow (/*@unused@*/ cppReader *p_pfile);\r
+\r
+static void cppReader_nullCleanup (/*@unused@*/ cppBuffer *p_pbuf,\r
+                                  /*@unused@*/ cppReader *p_pfile);\r
+\r
+static void cppReader_fileCleanup (cppBuffer *p_pbuf,\r
+                                  /*@unused@*/ cppReader *p_pfile);\r
+\r
+static int cppReader_handleDirective (cppReader *p_pfile);\r
+\r
+static void cppReader_scanBuffer (cppReader *p_pfile);\r
+\r
+# if defined (WIN32) || defined (OS2) && defined (__IBMC__)\r
+\r
+/*\r
+** WIN32 (at least the VC++ include files) does not define mode_t.\r
+*/\r
+\r
+/*@-incondefs@*/ /*@-czechtypes@*/\r
+typedef unsigned int mode_t;\r
+/*@=incondefs@*/ /*@=czechtypes@*/\r
+\r
+# endif\r
+\r
+static int file_size_and_mode (int p_fd, /*@out@*/ mode_t *p_mode_pointer,\r
+                              /*@out@*/ size_t *p_size_pointer);\r
+static int safe_read (int p_desc, /*@out@*/ char *p_ptr, int p_len);\r
+\r
+\r
+/*\r
+** cppBuffer_isMacro is true if the buffer contains macro expansion.\r
+** (Note that it is false while we're expanding marco *arguments*.)\r
+*/\r
+\r
+static bool cppBuffer_isMacro (/*@null@*/ cppBuffer *) /*@*/ ;\r
+\r
+static void path_include (cppReader *p_pfile, char *p_path)\r
+     /*@modifies p_pfile@*/ ;\r
+\r
+static void initialize_builtins (cppReader *p_pfile)\r
+     /*@modifies p_pfile@*/ ;\r
+\r
+static void initialize_char_syntax (struct cppOptions *p_opts) ;\r
+\r
+static int /*@alt void@*/ finclude (cppReader *p_pfile, int p_f,\r
+                                   cstring p_fname,\r
+                                   bool p_system_header_p,\r
+                                   /*@dependent@*/ /*@null@*/ struct file_name_list *p_dirptr);\r
+\r
+static void validate_else (cppReader *p_pfile, cstring p_directive);\r
+\r
+static void conditional_skip (cppReader *p_pfile, int p_skip,\r
+                             enum node_type p_type,\r
+                             /*@dependent@*/ /*@null@*/ char *p_control_macro);\r
+\r
+static HOST_WIDE_INT eval_if_expression (cppReader *p_pfile,\r
+                                        char *p_buf,\r
+                                        int p_length);\r
+\r
+static void skip_if_group (cppReader *p_pfile, int p_any);\r
+\r
+static bool comp_def_part (bool p_first, char *p_beg1, int p_len1,\r
+                          char *p_beg2, int p_len2, bool p_last);\r
+\r
+#ifdef abort\r
+extern void fancy_abort ();\r
+#endif\r
+\r
+static bool redundant_include_p (cppReader *p_pfile, /*@null@*/ cstring p_name);\r
+static bool is_system_include (cppReader *p_pfile, cstring p_filename);\r
+\r
+static /*@observer@*/ /*@null@*/ struct file_name_map *\r
+read_name_map (cppReader *p_pfile, cstring p_dirname);\r
+\r
+static cstring read_filename_string (int p_ch, /*:open:*/ FILE *p_f);\r
+\r
+static int open_include_file (cppReader *p_pfile,\r
+                             /*@owned@*/ cstring p_fname,\r
+                             /*@null@*/ struct file_name_list *p_searchptr);\r
+\r
+static void push_macro_expansion (cppReader *,\r
+                                 /*@owned@*/ char *, size_t,\r
+                                 /*@dependent@*/ hashNode);\r
+\r
+/* Last arg to output_line_command.  */\r
+enum file_change_code {\r
+  same_file, enter_file, leave_file\r
+};\r
+\r
+/* `struct directive' defines one #-directive, including how to handle it.  */\r
+\r
+struct directive {\r
+  int length;                  /* Length of name */\r
+  /*@null@*/ int (*func)();    /* Function to handle directive */\r
+  /*@observer@*/ cstring name; /* Name of directive */\r
+  enum node_type type;         /* Code which describes which directive.  */\r
+  bool command_reads_line;      /* One if rest of line is read by func.  */\r
+  bool traditional_comments;   /* Nonzero: keep comments if -traditional.  */\r
+  bool pass_thru;              /* Copy preprocessed directive to output file.*/\r
+};\r
+\r
+/* These functions are declared to return int instead of void since they\r
+   are going to be placed in a table and some old compilers have trouble with\r
+   pointers to functions returning void.  */\r
+\r
+static int do_define (cppReader *, /*@null@*/ struct directive *, \r
+                     char *, char *);\r
+static int do_defineAux (cppReader *, /*@null@*/ struct directive *,\r
+                        char *, char *, bool);\r
+     \r
+static int do_line (cppReader *, /*@null@*/ struct directive *);\r
+static int do_include (cppReader *, struct directive *, char *, char *);\r
+static int do_undef (cppReader *, struct directive *, char *, char *);\r
+static int do_error (cppReader *, struct directive *, char *, char *);\r
+static int do_pragma (cppReader *, struct directive *, char *, char *);\r
+static int do_ident (cppReader *, struct directive *, char *, char *);\r
+static int do_if (cppReader *, struct directive *, char *, char *);\r
+static int do_xifdef (cppReader *, struct directive *, char *, char *);\r
+static int do_else (cppReader *, struct directive *, char *, char *);\r
+static int do_elif (cppReader *, struct directive *, char *, char *);\r
+static int do_endif (cppReader *, struct directive *, char *, char *);\r
+static int do_warning (cppReader *, struct directive *, char *, char *);\r
+\r
+/* If a buffer's dir field is SELF_DIR_DUMMY, it means the file was found\r
+   via the same directory as the file that #included it.  */\r
+\r
+/*@constant observer struct file_name_list *SELF_DIR_DUMMY@*/\r
+#define SELF_DIR_DUMMY ((struct file_name_list *) (~0))\r
+\r
+/* #include "file" looks in source file dir, then stack.  */\r
+/* #include <file> just looks in the stack.  */\r
+/* -I directories are added to the end, then the defaults are added.  */\r
+\r
+/*@access cstring@*/\r
+\r
+static struct default_include {\r
+  /*@dependent@*/ /*@observer@*/ cstring fname;        /* The name of the directory.  */\r
+  int cplusplus;               /* Only look here if we're compiling C++.  */\r
+  int cxx_aware;               /* Includes in this directory don't need to\r
+                                  be wrapped in extern "C" when compiling\r
+                                  C++.  */\r
+} include_defaults_array[]\r
+= {\r
+  /* This is the dir for fixincludes.  Put it just before\r
+     the files that we fix.  */\r
+  { GCC_INCLUDE_DIR, 0, 0 },\r
+  { GCC_INCLUDE_DIR2, 0, 0 },\r
+  { cstring_undefined, 0, 0 }\r
+};\r
+\r
+/*@noaccess cstring@*/\r
+\r
+/* Here is the actual list of #-directives, most-often-used first.\r
+   The initialize_builtins function assumes #define is the very first.  */\r
+\r
+/*@access cstring@*/\r
+\r
+static struct directive directive_table[] = {\r
+  {  6, do_define, "define", T_DEFINE, FALSE, TRUE, FALSE },\r
+  {  5, do_xifdef, "ifdef", T_IFDEF, TRUE, FALSE, FALSE },\r
+  {  6, do_xifdef, "ifndef", T_IFNDEF, TRUE, FALSE, FALSE },\r
+  {  7, do_include, "include", T_INCLUDE, TRUE, FALSE, FALSE },\r
+  {  5, do_endif, "endif", T_ENDIF, TRUE, FALSE, FALSE },\r
+  {  4, do_else, "else", T_ELSE, TRUE, FALSE, FALSE },\r
+  {  2, do_if, "if", T_IF, TRUE, FALSE, FALSE },\r
+  {  4, do_elif, "elif", T_ELIF, TRUE, FALSE, FALSE },\r
+  {  5, do_undef, "undef", T_UNDEF, FALSE, FALSE, FALSE },\r
+  {  5, do_error, "error", T_ERROR, FALSE, FALSE, FALSE },\r
+  {  7, do_warning, "warning", T_WARNING, FALSE, FALSE, FALSE },\r
+  {  6, do_pragma, "pragma", T_PRAGMA, FALSE, FALSE, TRUE},\r
+  {  4, do_line, "line", T_LINE, TRUE, FALSE, FALSE },\r
+  {  5, do_ident, "ident", T_IDENT, TRUE, FALSE, TRUE },\r
+  /* {  8, do_unassert, "unassert", T_UNASSERT, TRUE, FALSE, FALSE }, */\r
+  {  -1, 0, "", T_UNUSED, FALSE, FALSE, FALSE },\r
+};\r
+/*@noaccess cstring@*/\r
+\r
+static cstring searchPath_unparse (struct file_name_list *search_start) \r
+{\r
+  cstring res = cstring_newEmpty ();\r
+  struct file_name_list *searchptr = NULL;\r
+\r
+  for (searchptr = search_start; searchptr != NULL;\r
+       searchptr = searchptr->next)\r
+    {\r
+      if (!cstring_isEmpty (searchptr->fname)) {\r
+       res = cstring_concatFree1 (res, searchptr->fname);\r
+       if (searchptr->next != NULL) {\r
+         res = cstring_appendChar (res, ';');\r
+       }\r
+      }\r
+    }\r
+\r
+  return res;\r
+}\r
+\r
+/*@+charint@*/\r
+static void\r
+initialize_char_syntax (struct cppOptions *opts)\r
+{\r
+  char i;\r
+\r
+  /*\r
+   * Set up is_idchar and is_idstart tables.  These should be\r
+   * faster than saying (is_alpha (c) || c == '_'), etc.\r
+   * Set up these things before calling any routines tthat\r
+   * refer to them.\r
+   */\r
+\r
+  for (i = 'a'; i <= 'z'; i++) {\r
+    is_idchar[i - 'a' + 'A'] = TRUE;\r
+    is_idchar[(int) i] = TRUE;\r
+    is_idstart[i - 'a' + 'A'] = TRUE;\r
+    is_idstart[(int) i] = TRUE;\r
+  }\r
+\r
+  for (i = '0'; i <= '9'; i++)\r
+    {\r
+      is_idchar[(int) i] = TRUE;\r
+    }\r
+\r
+  is_idchar['_'] = TRUE;\r
+  is_idstart['_'] = TRUE;\r
+  is_idchar['$'] = opts->dollars_in_ident;\r
+  is_idstart['$'] = opts->dollars_in_ident;\r
+\r
+  /* horizontal space table */\r
+  is_hor_space[' '] = TRUE;\r
+  is_hor_space['\t'] = TRUE;\r
+  is_hor_space['\v'] = TRUE;\r
+  is_hor_space['\f'] = TRUE;\r
+  is_hor_space['\r'] = TRUE;\r
+\r
+  is_space[' '] = TRUE;\r
+  is_space['\t'] = TRUE;\r
+  is_space['\v'] = TRUE;\r
+  is_space['\f'] = TRUE;\r
+  is_space['\n'] = TRUE;\r
+  is_space['\r'] = TRUE;\r
+}\r
+\r
+bool isIdentifierChar (char c)\r
+{\r
+  return is_idchar[(int) c];\r
+}\r
+\r
+/* Place into P_PFILE a quoted string representing the string SRC.\r
+   Caller must reserve enough space in pfile->token_buffer.  */\r
+\r
+static void\r
+quote_string (cppReader *pfile, char *src)\r
+{\r
+  char c;\r
+\r
+  cppReader_putCharQ (pfile, '\"');\r
+  for (;;)\r
+    {\r
+      switch ((c = *src++))\r
+       {\r
+       default:\r
+         if (isprint (c))\r
+           cppReader_putCharQ (pfile, c);\r
+         else\r
+           {\r
+             sprintf (cppReader_getPWritten (pfile), "\\%03o",\r
+                      (unsigned int) c);\r
+             cppReader_adjustWritten (pfile, (size_t) 4);\r
+           }\r
+         /*@switchbreak@*/ break;\r
+\r
+       case '\"':\r
+       case '\\':\r
+         cppReader_putCharQ (pfile, '\\');\r
+         cppReader_putCharQ (pfile, c);\r
+         /*@switchbreak@*/ break;\r
+\r
+       case '\0':\r
+         cppReader_putCharQ (pfile, '\"');\r
+         cppReader_nullTerminateQ (pfile);\r
+         return;\r
+       }\r
+    }\r
+}\r
+\r
+/* Re-allocates PFILE->token_buffer so it will hold at least N more chars.  */\r
+\r
+void\r
+cppReader_growBuffer (cppReader *pfile, size_t n)\r
+{\r
+  size_t old_written = cppReader_getWritten (pfile);\r
+  pfile->token_buffer_size = n + 2 * pfile->token_buffer_size;\r
+  pfile->token_buffer = (char *)\r
+    drealloc (pfile->token_buffer, pfile->token_buffer_size);\r
+  cppReader_setWritten (pfile, old_written);\r
+}\r
+\r
+/*\r
+ * process a given definition string, for initialization\r
+ * If STR is just an identifier, define it with value 1.\r
+ * If STR has anything after the identifier, then it should\r
+ * be identifier=definition.\r
+ */\r
+\r
+void\r
+cppReader_define (cppReader *pfile, char *str)\r
+{\r
+  char *buf = NULL;\r
+  char *p = str;\r
+\r
+  DPRINTF (("Cpp reader define: %s", str));\r
+\r
+  if (!is_idstart[(int) *p])\r
+    {\r
+      DPRINTF (("ERROR 1"));\r
+      cppReader_error (pfile,\r
+                      message ("Malformed option `-D%s'",\r
+                               cstring_fromChars (str)));\r
+      \r
+      return;\r
+    }\r
+\r
+  p++;\r
+\r
+  DPRINTF (("Here 2"));\r
+\r
+  while (is_idchar[(int) *p])\r
+    {\r
+      p++;\r
+    }\r
+\r
+  if (*p == '(') {\r
+    p++;\r
+    while (*p != ')' && *p != '\0') {\r
+      p++;\r
+    }\r
+\r
+    if (*p == ')') {\r
+      p++;\r
+    } else {\r
+      cppReader_error \r
+       (pfile,\r
+        message ("Malformed option: -D%s (no closing parenthesis)", \r
+                 cstring_fromChars (str)));\r
+    }\r
+  }\r
+\r
+  DPRINTF (("Here 2"));\r
+\r
+  if (*p == '\0')\r
+    {\r
+      buf = (char *) dmalloc (size_fromInt (p - str + 4));\r
+      strcpy ((char *) buf, str);\r
+      strcat ((char *) buf, " 1");\r
+    }\r
+  else if (*p != '=')\r
+    {\r
+      DPRINTF (("ERROR 2"));\r
+      cppReader_error (pfile,\r
+                      message ("Malformed option: -D%s (expected '=', found '%c')",\r
+                               cstring_fromChars (str),\r
+                               *p));\r
+      return;\r
+    }\r
+  else\r
+    {\r
+      char *q;\r
+      /* Copy the entire option so we can modify it.  */\r
+      DPRINTF (("Copying..."));\r
+      buf = (char *) dmalloc (2 * strlen (str) + 1);\r
+      strncpy (buf, str, size_fromInt (p - str));\r
+\r
+      /* Change the = to a space.  */\r
+      buf[p - str] = ' ';\r
+      /* Scan for any backslash-newline and remove it.  */\r
+      p++;\r
+      q = &buf[p - str];\r
+\r
+      while (*p != '\0')\r
+       {\r
+         if (*p == '\\' && p[1] == '\n')\r
+           p += 2;\r
+         else\r
+           *q++ = *p++;\r
+       }\r
+\r
+      DPRINTF (("Here we are..."));\r
+      *q = '\0';\r
+    }\r
+\r
+  llassert (buf != NULL);\r
+  DPRINTF (("Do define: %s / %ld", buf, size_toLong (strlen (buf))));\r
+  (void) do_define (pfile, NULL, buf, buf + strlen (buf));\r
+  sfree (buf);\r
+}\r
+\r
+/* Append a chain of `struct file_name_list's\r
+   to the end of the main include chain.\r
+   FIRST is gthe beginning of the chain to append, and LAST is the end.  */\r
+\r
+void\r
+cppReader_appendIncludeChain (cppReader *pfile,\r
+                     struct file_name_list *first,\r
+                     struct file_name_list *last)\r
+{\r
+  struct cppOptions *opts = CPPOPTIONS (pfile);\r
+  struct file_name_list *dir;\r
+\r
+  if (first == NULL || last == NULL)\r
+    {\r
+      return;\r
+    }\r
+\r
+  if (opts->include == 0)\r
+    {\r
+      opts->include = first;\r
+    }\r
+  else\r
+    {\r
+      llassert (opts->last_include->next == NULL);\r
+      opts->last_include->next = first;\r
+    }\r
+\r
+  if (opts->first_bracket_include == 0)\r
+    {\r
+      opts->first_bracket_include = first;\r
+\r
+      for (dir = first; ; dir = dir->next) {\r
+       int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;\r
+       if (len > pfile->max_include_len)\r
+         pfile->max_include_len = len;\r
+       if (dir == last)\r
+         break;\r
+      }\r
+    }\r
+\r
+  llassert (last->next == NULL);\r
+  /* last->next = NULL; */\r
+  opts->last_include = last;\r
+}\r
+\r
+# if 0\r
+static /*@unused@*/ void \r
+cppReader_showIncludeChain (cppReader *pfile)\r
+{\r
+  struct file_name_list *dirs = CPPOPTIONS (pfile)->include;\r
+\r
+  if (dirs != NULL)\r
+    {\r
+      while (dirs != NULL)\r
+       {\r
+         fprintf (stderr, "*%s*:", cstring_toCharsSafe (dirs->fname));\r
+         dirs = dirs->next;\r
+       }\r
+\r
+      fprintf (stderr, "\n");\r
+    }\r
+  else\r
+    {\r
+      fprintf (stderr, "No includes\n");\r
+    }\r
+}\r
+# endif\r
+\r
+cstring \r
+cppReader_getIncludePath ()\r
+{\r
+  cppReader *pfile = &g_cppState;\r
+  struct file_name_list *dirs = CPPOPTIONS (pfile)->include;\r
+  cstring res = cstring_undefined;\r
+\r
+  if (dirs != NULL)\r
+    {\r
+      while (dirs != NULL)\r
+       {\r
+         res = message ("%q%c%s", res, PATH_SEPARATOR, dirs->fname);\r
+         dirs = dirs->next;\r
+       }\r
+    }\r
+  else\r
+    {\r
+      res = cstring_makeLiteral ("<no include path>");\r
+    }\r
+\r
+  return res;\r
+}\r
+\r
+void\r
+cppReader_addIncludeChain (cppReader *pfile, struct file_name_list *dir)\r
+{\r
+  struct cppOptions *opts = CPPOPTIONS (pfile);\r
+\r
+  if (dir == 0)\r
+    {\r
+      return;\r
+    }\r
+\r
+  if (opts->include == 0)\r
+    {\r
+      opts->include = dir;\r
+    }\r
+  else\r
+    {\r
+      llassert (opts->last_include->next == NULL);\r
+      opts->last_include->next = dir;\r
+    }\r
+\r
+  if (opts->first_bracket_include == 0)\r
+    {\r
+      int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;\r
+      opts->first_bracket_include = dir;\r
+      if (len > pfile->max_include_len)\r
+       {\r
+         pfile->max_include_len = len;\r
+       }\r
+    }\r
+\r
+  dir->next = NULL;\r
+  opts->last_include = dir;\r
+  /* cppReader_showIncludeChain (pfile); */\r
+}\r
+\r
+/* Given a colon-separated list of file names PATH,\r
+   add all the names to the search path for include files.  */\r
+\r
+static void\r
+path_include (cppReader *pfile, char *path)\r
+{\r
+  char *p;\r
+\r
+#ifdef __CYGWIN32__\r
+  char *win32temp;\r
+\r
+  /* if we have a posix path list, convert to win32 path list */\r
+  win32temp = (char *) dmalloc /*@i4@*/\r
+    (cygwin32_posix_to_win32_path_list_buf_size (path));\r
+  cygwin32_posix_to_win32_path_list (path, win32temp);\r
+  path = win32temp;\r
+#endif\r
+\r
+  p = path;\r
+\r
+  if (*p != '\0')\r
+    while (1) {\r
+      char *q = p;\r
+      char *name;\r
+      struct file_name_list *dirtmp;\r
+\r
+      /* Find the end of this name.  */\r
+      while (*q != '\0' && *q != PATH_SEPARATOR)\r
+       {\r
+         q++;\r
+       }\r
+\r
+      if (p == q)\r
+       {\r
+         /* An empty name in the path stands for the current directory.  */\r
+         name = (char *) dmalloc ((size_t) 2);\r
+         name[0] = '.';\r
+         name[1] = '\0';\r
+       }\r
+      else\r
+       {\r
+         /* Otherwise use the directory that is named.  */\r
+         name = (char *) dmalloc (size_fromInt (q - p + 1));\r
+         memcpy (name, p, size_fromInt (q - p));\r
+         name[q - p] = '\0';\r
+       }\r
+\r
+      dirtmp = (struct file_name_list *) dmalloc (sizeof (*dirtmp));\r
+      dirtmp->next = 0;                /* New one goes on the end */\r
+      dirtmp->control_macro = 0;\r
+      dirtmp->c_system_include_path = 0;\r
+      dirtmp->fname = cstring_fromChars (name);\r
+      dirtmp->got_name_map = 0;\r
+      cppReader_addIncludeChain (pfile, dirtmp);\r
+\r
+      /* Advance past this name.  */\r
+      p = q;\r
+      if (*p == '\0')\r
+       break;\r
+      /* Skip the colon.  */\r
+      p++;\r
+    }\r
+}\r
+\r
+void\r
+cppOptions_init (cppOptions *opts)\r
+{\r
+  memset ((char *) opts, 0, sizeof *opts);\r
+  assertSet (opts);\r
+\r
+  opts->in_fname = NULL;\r
+  opts->out_fname = NULL;\r
+\r
+  /* Initialize is_idchar to allow $.  */\r
+  opts->dollars_in_ident = TRUE;\r
+\r
+  opts->no_line_commands = 0;\r
+  opts->no_trigraphs = TRUE;\r
+  opts->put_out_comments = 1;\r
+  opts->print_include_names = 0;\r
+  opts->dump_macros = DUMP_DEFINITIONS; /* DUMP_NONE; */\r
+  opts->no_output = 0;\r
+  opts->cplusplus = 0;\r
+\r
+  opts->cplusplus_comments = 1;\r
+  opts->verbose = 0;\r
+  opts->lang_asm = 0;\r
+  opts->for_lint = 0;\r
+  opts->chill = 0;\r
+  opts->pedantic_errors = 0;\r
+  opts->warn_comments = 0;\r
+  opts->warnings_are_errors = 0;\r
+\r
+  initialize_char_syntax (opts);\r
+}\r
+\r
+enum cpp_token\r
+cppReader_nullUnderflow (/*@unused@*/ cppReader *pfile)\r
+{\r
+  return CPP_EOF;\r
+}\r
+\r
+void\r
+cppReader_nullCleanup (/*@unused@*/ cppBuffer *pbuf,\r
+             /*@unused@*/ cppReader *pfile)\r
+{\r
+  ;\r
+}\r
+\r
+void\r
+cppReader_macroCleanup (cppBuffer *pbuf, /*@unused@*/ cppReader *pfile)\r
+{\r
+  hashNode macro = pbuf->hnode;\r
+\r
+  if (macro->type == T_DISABLED)\r
+    {\r
+      macro->type = T_MACRO;\r
+    }\r
+\r
+  if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)\r
+    {\r
+      sfree (pbuf->buf);\r
+      pbuf->buf = NULL;\r
+    }\r
+}\r
+\r
+void\r
+cppReader_fileCleanup (cppBuffer *pbuf, /*@unused@*/ cppReader *pfile)\r
+{\r
+  if (pbuf->buf != NULL)\r
+    {\r
+      sfree (pbuf->buf);\r
+      pbuf->buf = NULL;\r
+    }\r
+}\r
+\r
+/* Assuming we have read '/'.\r
+   If this is the start of a comment (followed by '*' or '/'),\r
+   skip to the end of the comment, and return ' '.\r
+   Return EOF if we reached the end of file before the end of the comment.\r
+   If not the start of a comment, return '/'.  */\r
+\r
+static int\r
+skip_comment (cppReader *pfile, /*@null@*/ long *linep)\r
+{\r
+  int c = 0;\r
+\r
+  llassert (pfile->buffer != NULL);\r
+  llassert (pfile->buffer->cur != NULL);\r
+\r
+  while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n')\r
+    {\r
+      if (linep != NULL)\r
+       {\r
+         (*linep)++;\r
+       }\r
+\r
+      cppReader_forward (pfile, 2);\r
+    }\r
+\r
+  if (cppReader_peekC (pfile) == '*')\r
+    {\r
+      cppReader_forward (pfile, 1);\r
+\r
+      for (;;)\r
+       {\r
+         int prev_c = c;\r
+         c = cppReader_getC (pfile);\r
+\r
+         if (c == EOF)\r
+           {\r
+             return EOF;\r
+           }\r
+\r
+         while (c == (int) '\\' && cppReader_peekC (pfile) == (int) '\n')\r
+           {\r
+             if (linep != NULL )\r
+               {\r
+                 (*linep)++;\r
+               }\r
+\r
+             cppReader_forward (pfile, 1), c = cppReader_getC (pfile);\r
+           }\r
+\r
+         if (prev_c == (int) '*' && c == (int) '/')\r
+           {\r
+             return (int) ' ';\r
+           }\r
+\r
+         if (c == (int) '\n' && (linep != NULL))\r
+           {\r
+             (*linep)++;\r
+           }\r
+       }\r
+    }\r
+  else if (cppReader_peekC (pfile) == '/' \r
+          && CPPOPTIONS (pfile)->cplusplus_comments)\r
+    {\r
+      cppReader_forward (pfile, 1);\r
+\r
+      for (;;)\r
+       {\r
+         c = cppReader_getC (pfile);\r
+\r
+         if (c == EOF)\r
+           {\r
+             /* Allow hash comment to be terminated by EOF.  */\r
+             return (int) ' '; \r
+           }\r
+\r
+         while (c == (int) '\\' && cppReader_peekC (pfile) == '\n')\r
+           {\r
+             cppReader_forward (pfile, 1);\r
+             c = cppReader_getC (pfile);\r
+\r
+             if (linep != NULL)\r
+               {\r
+                 (*linep)++;\r
+               }\r
+           }\r
+\r
+         if (c == (int) '\n')\r
+           {\r
+             /* Don't consider final '\n' to be part of comment.  */\r
+             cppReader_forward (pfile, -1);\r
+             return (int) ' ';\r
+           }\r
+       }\r
+    }\r
+  else\r
+    {\r
+      return (int) '/';\r
+    }\r
+}\r
+\r
+/* Skip whitespace \-newline and comments.  Does not macro-expand.  */\r
+int /*@alt void@*/\r
+cppSkipHspace (cppReader *pfile)\r
+{\r
+  int nspaces = 0;\r
+\r
+  while (TRUE)\r
+    {\r
+      int c;\r
+\r
+      llassert (pfile->buffer != NULL);\r
+\r
+      c = cppReader_peekC (pfile);\r
+\r
+      if (c == EOF)\r
+       {\r
+         return 0; /* FIXME */\r
+       }\r
+\r
+      if (is_hor_space[c])\r
+       {\r
+         if ((c == '\f' || c == '\v') && cppReader_isPedantic (pfile))\r
+           cppReader_pedwarn (pfile,\r
+                        message ("%s in preprocessing directive",\r
+                                 c == '\f'\r
+                                 ? cstring_makeLiteralTemp ("formfeed")\r
+                                 : cstring_makeLiteralTemp ("vertical tab")));\r
+\r
+         nspaces++;\r
+         cppReader_forward (pfile, 1);\r
+       }\r
+      else if (c == '/')\r
+       {\r
+         cppReader_forward (pfile, 1);\r
+         c = skip_comment (pfile, NULL);\r
+\r
+         if (c == '/')\r
+           {\r
+             cppReader_forward (pfile, -1);\r
+           }\r
+\r
+         if (c == EOF || c == '/')\r
+           {\r
+             return nspaces;\r
+           }\r
+       }\r
+      else if (c == '\\' && cpp_peekN (pfile, 1) == '\n')\r
+       {\r
+         cppReader_forward (pfile, 2);\r
+       }\r
+      else if (c == '@' && CPPBUFFER (pfile)->has_escapes\r
+              && is_hor_space [cpp_peekN (pfile, 1)])\r
+       {\r
+         cppReader_forward (pfile, 2);\r
+       }\r
+      else\r
+       {\r
+         return nspaces;\r
+       }\r
+    }\r
+}\r
+\r
+/* Read the rest of the current line.\r
+   The line is appended to PFILE's output buffer.  */\r
+\r
+static void\r
+copy_rest_of_line (cppReader *pfile)\r
+{\r
+  struct cppOptions *opts = CPPOPTIONS (pfile);\r
+\r
+  for (;;)\r
+    {\r
+      int c;\r
+      int nextc;\r
+\r
+      llassert (pfile->buffer != NULL);\r
+\r
+      c = cppReader_getC (pfile);\r
+      switch (c)\r
+       {\r
+       case EOF:\r
+         goto end_directive;\r
+       case '\\':\r
+         if (cppReader_peekC (pfile) == '\n')\r
+           {\r
+             cppReader_forward (pfile, 1);\r
+             continue;\r
+           }\r
+\r
+       /*@fallthrough@*/ case '\'': case '\"':\r
+         goto scan_directive_token;\r
+\r
+       case '/':\r
+         nextc = cppReader_peekC (pfile);\r
+\r
+         /*\r
+         ** was (opts->cplusplus_comments && nextc == '*')\r
+         ** yoikes!\r
+         */\r
+\r
+         if (nextc == '*'\r
+             || (opts->cplusplus_comments && nextc == '/'))\r
+           {\r
+             goto scan_directive_token;\r
+           }\r
+         /*@switchbreak@*/ break;\r
+       case '\f':\r
+       case '\v':\r
+         if (cppReader_isPedantic (pfile))\r
+           cppReader_pedwarn (pfile,\r
+                        message ("%s in preprocessing directive",\r
+                                 c == '\f'\r
+                                 ? cstring_makeLiteralTemp ("formfeed")\r
+                                 : cstring_makeLiteralTemp ("vertical tab")));\r
+         /*@switchbreak@*/ break;\r
+\r
+       case '\n':\r
+         cppReader_forward (pfile, -1);\r
+         goto end_directive;\r
+       scan_directive_token:\r
+         cppReader_forward (pfile, -1);\r
+         (void) cppGetToken (pfile);\r
+         continue;\r
+       }\r
+      cppReader_putChar (pfile, c);\r
+    }\r
+end_directive: ;\r
+  cppReader_nullTerminate (pfile);\r
+}\r
+\r
+void\r
+cppReader_skipRestOfLine (cppReader *pfile)\r
+{\r
+  size_t old = cppReader_getWritten (pfile);\r
+  copy_rest_of_line (pfile);\r
+  cppReader_setWritten (pfile, old);\r
+}\r
+\r
+/* Handle a possible # directive.\r
+   '#' has already been read.  */\r
+\r
+int\r
+cppReader_handleDirective (cppReader *pfile)\r
+{\r
+  int c;\r
+  struct directive *kt = NULL;\r
+  int ident_length;\r
+  size_t after_ident = 0;\r
+  char *ident = NULL;\r
+  char *line_end = NULL;\r
+  size_t old_written = cppReader_getWritten (pfile);\r
+  int nspaces = cppSkipHspace (pfile);\r
+\r
+  c = cppReader_peekC (pfile);\r
+\r
+  if (c >= '0' && c <= '9')\r
+    {\r
+      /* Handle # followed by a line number.  */\r
+      if (cppReader_isPedantic (pfile))\r
+       {\r
+         cppReader_pedwarnLit\r
+           (pfile,\r
+            cstring_makeLiteralTemp ("`#' followed by integer"));\r
+       }\r
+\r
+      (void) do_line (pfile, NULL);\r
+      goto done_a_directive;\r
+    }\r
+\r
+\r
+  /* Now find the directive name.  */\r
+\r
+  cppReader_putChar (pfile, '#');\r
+\r
+  parse_name (pfile, cppReader_getC (pfile));\r
+\r
+  llassert (pfile->token_buffer != NULL);\r
+  ident = pfile->token_buffer + old_written + 1;\r
+\r
+  ident_length = cppReader_getPWritten (pfile) - ident;\r
+\r
+  if (ident_length == 0 && cppReader_peekC (pfile) == '\n')\r
+    {\r
+      /* A line of just `#' becomes blank.  */\r
+      return 1; \r
+    }\r
+\r
+  for (kt = directive_table; ; kt++) \r
+    {\r
+      if (kt->length <= 0)\r
+       {\r
+         return 0; /* goto not_a_directive; */\r
+       }\r
+\r
+      if (kt->length == ident_length\r
+         && (cstring_equalPrefix (kt->name, cstring_fromChars (ident))))\r
+       {\r
+         break;\r
+       }\r
+    }\r
+\r
+  if (kt->command_reads_line)\r
+    {\r
+      after_ident = 0;\r
+    }\r
+  else\r
+    {\r
+      /* Nonzero means do not delete comments within the directive.\r
+        #define needs this when -traditional.  */\r
+      bool comments = 1; /*cppReader_isTraditional (pfile) && kt->traditional_comments;  */\r
+      int save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;\r
+      CPPOPTIONS (pfile)->put_out_comments = comments;\r
+      after_ident = cppReader_getWritten (pfile);\r
+      copy_rest_of_line (pfile);\r
+      CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;\r
+    }\r
+\r
+\r
+  /* For #pragma and #define, we may want to pass through the directive.\r
+     Other directives may create output, but we don't want the directive\r
+     itself out, so we pop it now.  For example #include may write a #line\r
+     command (see comment in do_include), and conditionals may emit\r
+     #failed ... #endfailed stuff.  But note that popping the buffer\r
+     means the parameters to kt->func may point after pfile->limit\r
+     so these parameters are invalid as soon as something gets appended\r
+     to the token_buffer.  */\r
+\r
+  line_end = cppReader_getPWritten (pfile);\r
+\r
+\r
+  if (!kt->pass_thru && kt->type != T_DEFINE)\r
+    {\r
+      cppReader_setWritten (pfile, old_written);\r
+    }\r
+\r
+  llassert (pfile->token_buffer != NULL);\r
+\r
+  /* was kt->pass_thru || */\r
+\r
+  if (kt->type == T_DEFINE\r
+      && cpp_shouldCheckMacro (pfile, pfile->token_buffer + old_written))\r
+    {\r
+      char *p = pfile->token_buffer + old_written;\r
+\r
+      /*\r
+      ** Still need to record value for preprocessing, so \r
+      ** #ifdef's, etc. using the value behave correctly.\r
+      */\r
+      \r
+      (void) do_defineAux (pfile, kt, \r
+                          pfile->token_buffer + after_ident,\r
+                          line_end,\r
+                          TRUE);\r
+      \r
+      if (*p == '#')\r
+       {\r
+         *p = ' ';\r
+       }\r
+\r
+      SKIP_WHITE_SPACE (p);\r
+\r
+      llassert (*p == 'd');\r
+      *p++ = LLMRCODE[0];\r
+\r
+      llassert (*p == 'e');\r
+      *p++ = LLMRCODE[1];\r
+\r
+      llassert (*p == 'f');\r
+      *p++ = LLMRCODE[2];\r
+\r
+      llassert (*p == 'i');\r
+      *p++ = LLMRCODE[3];\r
+\r
+      llassert (*p == 'n');\r
+      *p++ = LLMRCODE[4];\r
+\r
+      llassert (*p == 'e');\r
+\r
+      /*\r
+      ** This is way-bogus.  We use the last char to record the number of\r
+      ** spaces.  Its too hard to get them back into the input stream.\r
+      */\r
+\r
+      if (nspaces > 9) nspaces = 9;\r
+\r
+      *p++ = '0' + nspaces;\r
+\r
+      return 0; /* not_a_directive */\r
+    }\r
+  else if (kt->pass_thru)\r
+    {\r
+      /* Just leave the entire #define in the output stack.  */\r
+      return 0; /* not_a_directive */\r
+\r
+    }\r
+  else if (kt->type == T_DEFINE\r
+          && CPPOPTIONS (pfile)->dump_macros == DUMP_NAMES)\r
+    {\r
+      char *p = pfile->token_buffer + old_written + 7;  /* Skip "#define". */\r
+      SKIP_WHITE_SPACE (p);\r
+\r
+      while (is_idchar[(int) *p])\r
+       {\r
+         p++;\r
+       }\r
+\r
+      pfile->limit = p;\r
+      cppReader_putChar (pfile, '\n');\r
+    }\r
+  else if (kt->type == T_DEFINE)\r
+    {\r
+      cppReader_setWritten (pfile, old_written);\r
+    }\r
+  else\r
+    {\r
+      ;\r
+    }\r
+\r
+done_a_directive:\r
+  if (kt == NULL) {\r
+    return 1;\r
+  } else {\r
+    llassert (kt->func != NULL);\r
+    (void) (kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end);\r
+    return 1;\r
+  }\r
+}\r
+\r
+/* Pass a directive through to the output file.\r
+   BUF points to the contents of the directive, as a contiguous string.\r
+   LIMIT points to the first character past the end of the directive.\r
+   KEYWORD is the keyword-table entry for the directive.  */\r
+\r
+static void\r
+pass_thru_directive (char *buf, char *limit,\r
+                    cppReader *pfile,\r
+                    struct directive *keyword)\r
+{\r
+  int keyword_length = keyword->length;\r
+\r
+  cppReader_reserve (pfile,\r
+                    size_fromInt (2 + keyword_length + (limit - buf)));\r
+  cppReader_putCharQ (pfile, '#');\r
+  /*@-observertrans@*/\r
+  cppReader_putStrN (pfile, cstring_toCharsSafe (keyword->name),\r
+                    size_fromInt (keyword_length));\r
+  /*:=observertrans@*/\r
+\r
+  if (limit != buf && buf[0] != ' ')\r
+    {\r
+      /* Was a bug, since reserve only used 1 + ... */\r
+      cppReader_putCharQ (pfile, ' ');\r
+    }\r
+\r
+  cppReader_putStrN (pfile, buf, size_fromInt (limit - buf));\r
+}\r
+\r
+/* Read a replacement list for a macro with parameters.\r
+   Build the DEFINITION structure.\r
+   Reads characters of text starting at BUF until END.\r
+   ARGLIST specifies the formal parameters to look for\r
+   in the text of the definition; NARGS is the number of args\r
+   in that list, or -1 for a macro name that wants no argument list.\r
+   MACRONAME is the macro name itself (so we can avoid recursive expansion)\r
+   and NAMELEN is its length in characters.\r
+\r
+   Note that comments, backslash-newlines, and leading white space\r
+   have already been deleted from the argument.  */\r
+\r
+static DEFINITION *\r
+collect_expansion (cppReader *pfile, char *buf, char *limit,\r
+                  int nargs, /*@null@*/ struct arglist *arglist)\r
+{\r
+  DEFINITION *defn;\r
+  char *p, *lastp, *exp_p;\r
+  struct reflist *endpat = NULL;\r
+  /* Pointer to first nonspace after last ## seen.  */\r
+  char *concat = 0;\r
+  /* Pointer to first nonspace after last single-# seen.  */\r
+  char *stringify = 0;\r
+  size_t maxsize;\r
+  char expected_delimiter = '\0';\r
+\r
+\r
+  /* Scan thru the replacement list, ignoring comments and quoted\r
+     strings, picking up on the macro calls.  It does a linear search\r
+     thru the arg list on every potential symbol.  Profiling might say\r
+     that something smarter should happen.  */\r
+\r
+  if (limit < buf)\r
+    abort ();\r
+\r
+  /* Find the beginning of the trailing whitespace.  */\r
+  p = buf;\r
+\r
+  while (p < limit && is_space[(int) limit[-1]])\r
+    {\r
+      limit--;\r
+    }\r
+\r
+  /* Allocate space for the text in the macro definition.\r
+     Leading and trailing whitespace chars need 2 bytes each.\r
+     Each other input char may or may not need 1 byte,\r
+     so this is an upper bound.  The extra 5 are for invented\r
+     leading and trailing newline-marker and final null.  */\r
+  maxsize = (sizeof (*defn) + (limit - p) + 5);\r
+\r
+  /* Occurrences of '@' get doubled, so allocate extra space for them.  */\r
+  while (p < limit)\r
+    {\r
+      if (*p++ == '@')\r
+       {\r
+         maxsize++;\r
+       }\r
+    }\r
+\r
+  defn = (DEFINITION *) dmalloc (maxsize);\r
+  defn->noExpand = FALSE;\r
+  defn->file = NULL;\r
+  defn->pattern = NULL;\r
+  defn->nargs = nargs;\r
+  defn->predefined = NULL;\r
+\r
+  exp_p = defn->expansion = (char *) defn + sizeof (*defn);\r
+\r
+  defn->line = 0;\r
+  defn->rest_args = NULL;\r
+  defn->args.argnames = NULL;\r
+\r
+  lastp = exp_p;\r
+\r
+  p = buf;\r
+\r
+  /* Add one initial space escape-marker to prevent accidental\r
+     token-pasting (often removed by macroexpand).  */\r
+  *exp_p++ = '@';\r
+  *exp_p++ = ' ';\r
+\r
+  if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {\r
+    cppReader_errorLit (pfile,\r
+                       cstring_makeLiteralTemp ("`##' at start of macro definition"));\r
+    p += 2;\r
+  }\r
+\r
+  /* Process the main body of the definition.  */\r
+  while (p < limit) {\r
+    int skipped_arg = 0;\r
+    register char c = *p++;\r
+\r
+    *exp_p++ = c;\r
+\r
+    if (!cppReader_isTraditional (pfile)) {\r
+      switch (c) {\r
+      case '\'':\r
+      case '\"':\r
+       if (expected_delimiter != '\0')\r
+         {\r
+           if (c == expected_delimiter)\r
+             expected_delimiter = '\0';\r
+         }\r
+       else\r
+         {\r
+           expected_delimiter = c;\r
+         }\r
+       /*@switchbreak@*/ break;\r
+\r
+      case '\\':\r
+       if (p < limit && (expected_delimiter != '\0'))\r
+         {\r
+           /* In a string, backslash goes through\r
+              and makes next char ordinary.  */\r
+           *exp_p++ = *p++;\r
+         }\r
+       /*@switchbreak@*/ break;\r
+\r
+      case '@':\r
+       /* An '@' in a string or character constant stands for itself,\r
+          and does not need to be escaped.  */\r
+       if (expected_delimiter == '\0')\r
+         {\r
+           *exp_p++ = c;\r
+         }\r
+\r
+       /*@switchbreak@*/ break;\r
+\r
+      case '#':\r
+       /* # is ordinary inside a string.  */\r
+       if (expected_delimiter != '\0')\r
+         {\r
+           /*@switchbreak@*/ break;\r
+         }\r
+\r
+       if (p < limit && *p == '#') {\r
+         /* ##: concatenate preceding and following tokens.  */\r
+         /* Take out the first #, discard preceding whitespace.  */\r
+         exp_p--;\r
+\r
+         /*@-usedef@*/\r
+         while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])\r
+           {\r
+             --exp_p;\r
+           }\r
+         /*@=usedef@*/\r
+\r
+         /* Skip the second #.  */\r
+         p++;\r
+         /* Discard following whitespace.  */\r
+         SKIP_WHITE_SPACE (p);\r
+         concat = p;\r
+         if (p == limit)\r
+           {\r
+             cppReader_errorLit (pfile,\r
+                           cstring_makeLiteralTemp ("`##' at end of macro definition"));\r
+           }\r
+       } else if (nargs >= 0) {\r
+         /* Single #: stringify following argument ref.\r
+            Don't leave the # in the expansion.  */\r
+         exp_p--;\r
+         SKIP_WHITE_SPACE (p);\r
+         if (p == limit || ! is_idstart[(int) *p]\r
+             || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '"')))\r
+           cppReader_errorLit (pfile,\r
+                         cstring_makeLiteralTemp ("`#' operator is not followed by a macro argument name"));\r
+         else\r
+           stringify = p;\r
+       } else {\r
+         ; /* BADBRANCH; */\r
+       }\r
+\r
+       /*@switchbreak@*/ break;\r
+      }\r
+    } else {\r
+      /* In -traditional mode, recognize arguments inside strings and\r
+        and character constants, and ignore special properties of #.\r
+        Arguments inside strings are considered "stringified", but no\r
+        extra quote marks are supplied.  */\r
+      switch (c) {\r
+      case '\'':\r
+      case '\"':\r
+       if (expected_delimiter != '\0') {\r
+         if (c == expected_delimiter)\r
+           expected_delimiter = '\0';\r
+       } else\r
+         expected_delimiter = c;\r
+       /*@switchbreak@*/ break;\r
+\r
+      case '\\':\r
+       /* Backslash quotes delimiters and itself, but not macro args.  */\r
+       if (expected_delimiter != '\0' && p < limit\r
+           && (*p == expected_delimiter || *p == '\\')) {\r
+         *exp_p++ = *p++;\r
+         continue;\r
+       }\r
+       /*@switchbreak@*/ break;\r
+\r
+      case '/':\r
+       if (expected_delimiter != '\0') /* No comments inside strings.  */\r
+         /*@switchbreak@*/ break;\r
+       if (*p == '*') {\r
+         /* If we find a comment that wasn't removed by cppReader_handleDirective,\r
+            this must be -traditional.  So replace the comment with\r
+            nothing at all.  */\r
+         exp_p--;\r
+         p += 1;\r
+         while (p < limit && !(p[-2] == '*' && p[-1] == '/'))\r
+           {\r
+             p++;\r
+           }\r
+       }\r
+       /*@switchbreak@*/ break;\r
+      }\r
+    }\r
+\r
+    /* Handle the start of a symbol.  */\r
+    if (is_idchar[(int) c] && nargs > 0) {\r
+      char *id_beg = p - 1;\r
+      int id_len;\r
+\r
+      --exp_p;\r
+      while (p != limit && is_idchar[(int) *p])\r
+       {\r
+         p++;\r
+       }\r
+\r
+      id_len = p - id_beg;\r
+\r
+      if (is_idstart[(int) c]\r
+         && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {\r
+       register struct arglist *arg;\r
+\r
+       for (arg = arglist; arg != NULL; arg = arg->next) {\r
+         struct reflist *tpat;\r
+\r
+         if (arg->name[0] == c\r
+             && arg->length == id_len\r
+             && strncmp (arg->name, id_beg, size_fromInt (id_len)) == 0) {\r
+           char *p1;\r
+\r
+           if (expected_delimiter && CPPOPTIONS (pfile)->warn_stringify) {\r
+             if (cppReader_isTraditional (pfile)) {\r
+               cppReader_warning (pfile,\r
+                                  message ("macro argument `%x' is stringified.",\r
+                                           cstring_prefix (cstring_fromChars (arg->name), id_len)));\r
+             } else {\r
+               cppReader_warning (pfile,\r
+                                  message ("macro arg `%x' would be stringified with -traditional.",\r
+                                           cstring_prefix (cstring_fromChars (arg->name), id_len)));\r
+             }\r
+           }\r
+           /* If ANSI, don't actually substitute inside a string.  */\r
+           if (!cppReader_isTraditional (pfile) && expected_delimiter)\r
+             /*@innerbreak@*/ break;\r
+           /* make a pat node for this arg and append it to the end of\r
+              the pat list */\r
+           tpat = (struct reflist *) dmalloc (sizeof (*tpat));\r
+           tpat->next = NULL;\r
+           tpat->raw_before = (concat == id_beg);\r
+           tpat->raw_after = 0;\r
+           tpat->rest_args = arg->rest_args;\r
+           tpat->stringify = (cppReader_isTraditional (pfile)\r
+                              ? expected_delimiter != '\0'\r
+                              : stringify == id_beg);\r
+\r
+           if (endpat == NULL)\r
+             {\r
+               defn->pattern = tpat;\r
+             }\r
+           else\r
+             {\r
+               endpat->next = tpat;\r
+               /*@-branchstate@*/\r
+             } /*@=branchstate@*/ /* evs 2000 was =branchstate */\r
+\r
+           endpat = tpat;\r
+\r
+           tpat->argno = arg->argno;\r
+           tpat->nchars = exp_p - lastp;\r
+\r
+           p1 = p;\r
+\r
+           SKIP_WHITE_SPACE (p1);\r
+\r
+           if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')\r
+             {\r
+               tpat->raw_after = 1;\r
+             }\r
+\r
+           lastp = exp_p;      /* place to start copying from next time */\r
+           skipped_arg = 1;\r
+\r
+           /*@innerbreak@*/ break;\r
+         }\r
+       }\r
+      }\r
+\r
+      /* If this was not a macro arg, copy it into the expansion.  */\r
+      if (skipped_arg == 0) {\r
+       register char *lim1 = p;\r
+       p = id_beg;\r
+\r
+       while (p != lim1)\r
+         {\r
+           *exp_p++ = *p++;\r
+         }\r
+\r
+       if (stringify == id_beg)\r
+         cppReader_errorLit (pfile,\r
+                             cstring_makeLiteralTemp ("`#' operator should be followed by a macro argument name"));\r
+      }\r
+    }\r
+  }\r
+\r
+  if (!cppReader_isTraditional (pfile) && expected_delimiter == '\0')\r
+    {\r
+      /* If ANSI, put in a "@ " marker to prevent token pasting.\r
+        But not if "inside a string" (which in ANSI mode\r
+        happens only for -D option).  */\r
+      *exp_p++ = '@';\r
+      *exp_p++ = ' ';\r
+    }\r
+\r
+  *exp_p = '\0';\r
+\r
+  defn->length = size_fromInt (exp_p - defn->expansion);\r
+\r
+  /* Crash now if we overrun the allocated size.  */\r
+  if (defn->length + 1 > maxsize)\r
+    {\r
+      llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));\r
+    }\r
+\r
+  return defn;\r
+}\r
+\r
+/*\r
+ * special extension string that can be added to the last macro argument to\r
+ * allow it to absorb the "rest" of the arguments when expanded.  Ex:\r
+ *             #define wow(a, b...)            process (b, a, b)\r
+ *             { wow (1, 2, 3); }      ->      { process (2, 3, 1, 2, 3); }\r
+ *             { wow (one, two); }     ->      { process (two, one, two); }\r
+ * if this "rest_arg" is used with the concat token '##' and if it is not\r
+ * supplied then the token attached to with ## will not be outputted.  Ex:\r
+ *             #define wow (a, b...)           process (b ## , a, ## b)\r
+ *             { wow (1, 2); }         ->      { process (2, 1, 2); }\r
+ *             { wow (one); }          ->      { process (one); {\r
+ */\r
+\r
+/*@-readonlytrans@*/\r
+static char rest_extension[] = "...";\r
+/*:=readonlytrans@*/\r
+\r
+/*@notfunction@*/\r
+#define REST_EXTENSION_LENGTH  (sizeof (rest_extension) - 1)\r
+\r
+/* Create a DEFINITION node from a #define directive.  Arguments are\r
+   as for do_define.  */\r
+\r
+static /*@null@*/ MACRODEF\r
+create_definition (char *buf, char *limit,\r
+                  cppReader *pfile, bool predefinition,\r
+                  bool noExpand)\r
+{\r
+  char *bp;                    /* temp ptr into input buffer */\r
+  char *symname;               /* remember where symbol name starts */\r
+  int sym_length;              /* and how long it is */\r
+  int rest_args = 0;   /* really int! */\r
+  int line;\r
+  int col;\r
+  cstring file = (CPPBUFFER (pfile) != NULL)\r
+    ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp ("");\r
+  DEFINITION *defn;\r
+  int arglengths = 0;          /* Accumulate lengths of arg names\r
+                                  plus number of args.  */\r
+  MACRODEF mdef;\r
+\r
+  cppBuffer_lineAndColumn (CPPBUFFER (pfile), &line, &col);\r
+\r
+  bp = buf;\r
+\r
+  while (is_hor_space[(int) *bp])\r
+    {\r
+      bp++;\r
+    }\r
+\r
+  symname = bp;                        /* remember where it starts */\r
+\r
+  sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro"));\r
+\r
+  bp += sym_length;\r
+\r
+  /* Lossage will occur if identifiers or control keywords are broken\r
+     across lines using backslash.  This is not the right place to take\r
+     care of that.  */\r
+\r
+  if (*bp == '(') {\r
+    struct arglist *arg_ptrs = NULL;\r
+    int argno = 0;\r
+\r
+    bp++;                      /* skip '(' */\r
+    SKIP_WHITE_SPACE (bp);\r
+\r
+    /* Loop over macro argument names.  */\r
+    while (*bp != ')')\r
+      {\r
+       struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));\r
+       temp->name = bp;\r
+       temp->next = arg_ptrs;\r
+       temp->argno = argno++;\r
+       temp->rest_args = 0;\r
+\r
+       arg_ptrs = temp;\r
+\r
+       if (rest_args != 0)\r
+         {\r
+           cppReader_pedwarn (pfile,\r
+                        message ("another parameter follows `%s'",\r
+                                 cstring_fromChars (rest_extension)));\r
+         }\r
+\r
+       if (!is_idstart[(int) *bp])\r
+         {\r
+           cppReader_pedwarnLit (pfile,\r
+                           cstring_makeLiteralTemp ("invalid character in macro parameter name"));\r
+         }\r
+\r
+       /* Find the end of the arg name.  */\r
+       while (is_idchar[(int) *bp])\r
+         {\r
+           bp++;\r
+           /* do we have a "special" rest-args extension here? */\r
+           if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)\r
+               && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)\r
+             {\r
+               rest_args = 1;\r
+               temp->rest_args = 1;\r
+               /*@innerbreak@*/ break;\r
+             }\r
+         }\r
+\r
+       temp->length = bp - temp->name;\r
+\r
+       if (rest_args != 0)\r
+         {\r
+           bp += REST_EXTENSION_LENGTH;\r
+         }\r
+\r
+       arglengths += temp->length + 2;\r
+       SKIP_WHITE_SPACE (bp);\r
+\r
+       if (temp->length == 0 || (*bp != ',' && *bp != ')')) {\r
+         cppReader_errorLit (pfile,\r
+                       cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));\r
+         goto nope;\r
+       }\r
+\r
+       if (*bp == ',') {\r
+         bp++;\r
+         SKIP_WHITE_SPACE (bp);\r
+       }\r
+       if (bp >= limit) {\r
+         cppReader_errorLit (pfile,\r
+                       cstring_makeLiteralTemp ("unterminated parameter list in `#define'"));\r
+         goto nope;\r
+       }\r
+       {\r
+         struct arglist *otemp;\r
+\r
+         for (otemp = temp->next; otemp != NULL; otemp = otemp->next)\r
+           {\r
+             if (temp->length == otemp->length &&\r
+                 strncmp (temp->name, otemp->name, size_fromInt (temp->length)) == 0) {\r
+               cstring name = cstring_copyLength (temp->name, temp->length);\r
+               cppReader_error (pfile,\r
+                          message ("duplicate argument name `%x' in `#define'", name));\r
+               goto nope;\r
+             }\r
+           }\r
+       }\r
+      }\r
+\r
+    ++bp;                      /* skip paren */\r
+    SKIP_WHITE_SPACE (bp);\r
+    /* now everything from bp before limit is the definition.  */\r
+    defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);\r
+    defn->rest_args = rest_args;\r
+    \r
+    /* Now set defn->args.argnames to the result of concatenating\r
+       the argument names in reverse order\r
+       with comma-space between them.  */\r
+    defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));\r
+\r
+    {\r
+      struct arglist *temp;\r
+      int i = 0;\r
+      for (temp = arg_ptrs; temp != NULL; temp = temp->next) {\r
+       memcpy (&defn->args.argnames[i], temp->name, size_fromInt (temp->length));\r
+       i += temp->length;\r
+       if (temp->next != 0) {\r
+         defn->args.argnames[i++] = ',';\r
+         defn->args.argnames[i++] = ' ';\r
+       }\r
+      }\r
+\r
+      defn->args.argnames[i] = '\0';\r
+    }\r
+\r
+    sfree (arg_ptrs);\r
+  } else {\r
+    /* Simple expansion or empty definition.  */\r
+\r
+    if (bp < limit)\r
+      {\r
+       if (is_hor_space[(int) *bp]) {\r
+         bp++;\r
+         SKIP_WHITE_SPACE (bp);\r
+       } else {\r
+         switch (*bp) {\r
+         case '!':  case '"':  case '#':  case '%':  case '&':  case '\'':\r
+         case ')':  case '*':  case '+':  case ',':  case '-':  case '.':\r
+         case '/':  case ':':  case ';':  case '<':  case '=':  case '>':\r
+         case '?':  case '[':  case '\\': case ']':  case '^':  case '{':\r
+         case '|':  case '}':  case '~':\r
+           cppReader_warning (pfile,\r
+                        message ("Missing white space after #define %x",\r
+                                 cstring_prefix (cstring_fromChars (symname),\r
+                                                 sym_length)));\r
+           break;\r
+\r
+         default:\r
+           cppReader_pedwarn (pfile,\r
+                        message ("Missing white space after #define %x",\r
+                                 cstring_prefix (cstring_fromChars (symname),\r
+                                                 sym_length)));\r
+           break;\r
+         }\r
+       }\r
+      }\r
+    /* now everything from bp before limit is the definition.  */\r
+    defn = collect_expansion (pfile, bp, limit, -1, NULL);\r
+    defn->args.argnames = mstring_createEmpty ();\r
+  }\r
+\r
+  defn->noExpand = noExpand;\r
+  DPRINTF (("No expand: %d", noExpand));\r
+\r
+  defn->line = line;\r
+\r
+  /* not: llassert (cstring_isUndefined (defn->file)); */\r
+  defn->file = file;\r
+\r
+  /* OP is null if this is a predefinition */\r
+  defn->predefined = predefinition;\r
+  mdef.defn = defn;\r
+  mdef.symnam = symname;\r
+  mdef.symlen = sym_length;\r
+\r
+  return mdef;\r
+\r
+nope:\r
+  mdef.defn = NULL;\r
+  mdef.symnam = NULL;\r
+  return mdef;\r
+}\r
+\r
+/* Check a purported macro name SYMNAME, and yield its length.\r
+   USAGE is the kind of name this is intended for.  */\r
+\r
+int cppReader_checkMacroName (cppReader *pfile,\r
+                     char *symname,\r
+                     cstring usage)\r
+{\r
+  char *p;\r
+  size_t sym_length;\r
+\r
+  for (p = symname; is_idchar[(int) *p]; p++)\r
+    {\r
+      ;\r
+    }\r
+\r
+  sym_length = size_fromInt (p - symname);\r
+\r
+  if (sym_length == 0\r
+      || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))\r
+    cppReader_error (pfile, message ("invalid %s name", usage));\r
+  else if (!is_idstart[(int) *symname])\r
+    {\r
+      char *msg = (char *) dmalloc (sym_length + 1);\r
+      memcpy (msg, symname, sym_length);\r
+      msg[sym_length] = '\0';\r
+      cppReader_error (pfile, message ("invalid %s name `%s'", usage,\r
+                                      cstring_fromChars (msg)));\r
+      sfree (msg);\r
+    }\r
+  else\r
+    {\r
+      if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7)\r
+       {\r
+         cppReader_error (pfile, message ("invalid %s name `defined'", usage));\r
+       }\r
+    }\r
+\r
+  return size_toInt (sym_length);\r
+}\r
+\r
+/* Return zero if two DEFINITIONs are isomorphic.  */\r
+\r
+static bool\r
+compare_defs (DEFINITION *d1, DEFINITION *d2)\r
+{\r
+  register struct reflist *a1, *a2;\r
+  register char *p1 = d1->expansion;\r
+  register char *p2 = d2->expansion;\r
+  bool first = TRUE;\r
+\r
+  if (d1->nargs != d2->nargs)\r
+    {\r
+      return TRUE;\r
+    }\r
+\r
+  llassert (d1->args.argnames != NULL);\r
+  llassert (d2->args.argnames != NULL);\r
+\r
+  if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames) != 0)\r
+    {\r
+      return TRUE;\r
+    }\r
+\r
+  for (a1 = d1->pattern, a2 = d2->pattern;\r
+       (a1 != NULL) && (a2 != NULL);\r
+       a1 = a1->next, a2 = a2->next) {\r
+    if (!((a1->nchars == a2->nchars\r
+          && (strncmp (p1, p2, size_fromInt (a1->nchars)) == 0))\r
+         || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))\r
+       || a1->argno != a2->argno\r
+       || a1->stringify != a2->stringify\r
+       || a1->raw_before != a2->raw_before\r
+       || a1->raw_after != a2->raw_after)\r
+      return TRUE;\r
+    first = 0;\r
+    p1 += a1->nchars;\r
+    p2 += a2->nchars;\r
+  }\r
+  if (a1 != a2)\r
+    return TRUE;\r
+\r
+  if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),\r
+                    p2, d2->length - (p2 - d2->expansion), 1))\r
+    return TRUE;\r
+\r
+  return FALSE;\r
+}\r
+\r
+/* Return TRUE if two parts of two macro definitions are effectively different.\r
+   One of the parts starts at BEG1 and has LEN1 chars;\r
+   the other has LEN2 chars at BEG2.\r
+   Any sequence of whitespace matches any other sequence of whitespace.\r
+   FIRST means these parts are the first of a macro definition;\r
+   so ignore leading whitespace entirely.\r
+   LAST means these parts are the last of a macro definition;\r
+   so ignore trailing whitespace entirely.  */\r
+\r
+static bool\r
+comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last)\r
+{\r
+  char *end1 = beg1 + len1;\r
+  char *end2 = beg2 + len2;\r
+\r
+  if (first) {\r
+    while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }\r
+    while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }\r
+  }\r
+  if (last) {\r
+    while (beg1 != end1 && is_space[(int) end1[-1]]) { end1--; }\r
+    while (beg2 != end2 && is_space[(int) end2[-1]]) { end2--; }\r
+  }\r
+  while (beg1 != end1 && beg2 != end2) {\r
+    if (is_space[(int) *beg1] && is_space[(int) *beg2]) {\r
+      while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }\r
+      while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }\r
+    } else if (*beg1 == *beg2) {\r
+      beg1++; beg2++;\r
+    } else break;\r
+  }\r
+  return (beg1 != end1) || (beg2 != end2);\r
+}\r
+\r
+/* Process a #define command.\r
+   BUF points to the contents of the #define command, as a contiguous string.\r
+   LIMIT points to the first character past the end of the definition.\r
+   KEYWORD is the keyword-table entry for #define,\r
+   or NULL for a "predefined" macro.  */\r
+\r
+static int\r
+do_defineAux (cppReader *pfile, struct directive *keyword,\r
+             char *buf, char *limit, bool noExpand)\r
+{\r
+  int hashcode;\r
+  MACRODEF mdef;\r
+  hashNode hp;\r
+  \r
+  DPRINTF (("Define aux: %d", noExpand));\r
+\r
+  mdef = create_definition (buf, limit, pfile, keyword == NULL, noExpand);\r
+\r
+  if (mdef.defn == 0)\r
+    goto nope;\r
+\r
+  hashcode = hashf (mdef.symnam, mdef.symlen, CPP_HASHSIZE);\r
+\r
+  DPRINTF (("Macro: %s / %s", \r
+           cstring_copyLength (mdef.symnam, mdef.symlen),\r
+           bool_unparse (noExpand)));\r
+\r
+  if ((hp = cppReader_lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL)\r
+    {\r
+      bool ok = FALSE;\r
+\r
+      /* Redefining a precompiled key is ok.  */\r
+      if (hp->type == T_PCSTRING)\r
+       ok = TRUE;\r
+      /* Redefining a macro is ok if the definitions are the same.  */\r
+      else if (hp->type == T_MACRO)\r
+       ok = !compare_defs (mdef.defn, hp->value.defn);\r
+      /* Redefining a constant is ok with -D.  */\r
+      else if (hp->type == T_CONST)\r
+       ok = !CPPOPTIONS (pfile)->done_initializing;\r
+      else {\r
+       BADBRANCH;\r
+      }\r
+\r
+      /* Print the warning if it's not ok.  */\r
+      if (!ok)\r
+       {\r
+         /*\r
+         ** If we are passing through #define and #undef directives, do\r
+         ** that for this re-definition now.\r
+         */\r
+\r
+         if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))\r
+           {\r
+             /* llassert (keyword != NULL); */\r
+             pass_thru_directive (buf, limit, pfile, keyword);\r
+           }\r
+\r
+         cpp_setLocation (pfile);\r
+\r
+         if (hp->type == T_MACRO)\r
+           {\r
+             if (hp->value.defn->noExpand)\r
+               {\r
+                 ; /* error will be reported checking macros */\r
+               }\r
+             else\r
+               {\r
+                 genppllerrorhint\r
+                   (FLG_MACROREDEF,\r
+                    message ("Macro %q already defined",\r
+                             cstring_copyLength (mdef.symnam, mdef.symlen)),\r
+                    message ("%q: Previous definition of %q",\r
+                             fileloc_unparseRaw (hp->value.defn->file,\r
+                                                (int) hp->value.defn->line),\r
+                             cstring_copyLength (mdef.symnam, mdef.symlen)));\r
+               }\r
+           }\r
+         else\r
+           {\r
+             genppllerror (FLG_MACROREDEF,\r
+                           message ("Macro %q already defined",\r
+                                    cstring_copyLength (mdef.symnam,\r
+                                                        mdef.symlen)));\r
+\r
+           }\r
+       }\r
+\r
+      /* Replace the old definition.  */\r
+      hp->type = T_MACRO;\r
+      hp->value.defn = mdef.defn;\r
+    }\r
+  else\r
+    {\r
+      /*\r
+      ** If we are passing through #define and #undef directives, do\r
+      ** that for this new definition now.\r
+      */\r
+\r
+      hashNode hn;\r
+\r
+      if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))\r
+       {\r
+         pass_thru_directive (buf, limit, pfile, keyword);\r
+       }\r
+\r
+      DPRINTF (("Define macro: %s / %d", \r
+               mdef.symnam, mdef.defn->noExpand));\r
+      \r
+      hn = cppReader_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);\r
+      /*@-branchstate@*/\r
+    } /*@=branchstate@*/\r
+\r
+  return 0;\r
+\r
+nope:\r
+\r
+  return 1;\r
+}\r
+\r
+static int\r
+do_define (cppReader *pfile, struct directive *keyword,\r
+          char *buf, char *limit)\r
+{\r
+  DPRINTF (("Regular do define"));\r
+  return do_defineAux (pfile, keyword, buf, limit, FALSE);\r
+}\r
+\r
+/* This structure represents one parsed argument in a macro call.\r
+   `raw' points to the argument text as written (`raw_length' is its length).\r
+   `expanded' points to the argument's macro-expansion\r
+   (its length is `expand_length').\r
+   `stringified_length' is the length the argument would have\r
+   if stringified.\r
+   `use_count' is the number of times this macro arg is substituted\r
+   into the macro.  If the actual use count exceeds 10,\r
+   the value stored is 10.  */\r
+\r
+/* raw and expanded are relative to ARG_BASE */\r
+/*@notfunction@*/\r
+#define ARG_BASE ((pfile)->token_buffer)\r
+\r
+struct argdata {\r
+  /* Strings relative to pfile->token_buffer */\r
+  long raw;\r
+  size_t expanded;\r
+  size_t stringified;\r
+  int raw_length;\r
+  int expand_length;\r
+  int stringified_length;\r
+  bool newlines;\r
+  int use_count;\r
+};\r
+\r
+/* Allocate a new cppBuffer for PFILE, and push it on the input buffer stack.\r
+   If BUFFER != NULL, then use the LENGTH characters in BUFFER\r
+   as the new input buffer.\r
+   Return the new buffer, or NULL on failure.  */\r
+\r
+/*@null@*/ /*@exposed@*/ cppBuffer *\r
+cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length)\r
+{\r
+  cppBuffer *buf = cppReader_getBuffer (pfile);\r
+\r
+  if (buf == pfile->buffer_stack)\r
+    {\r
+      cppReader_fatalError\r
+       (pfile,\r
+        message ("%s: macro or `#include' recursion too deep",\r
+                 (buf->fname != NULL)\r
+                 ? buf->fname\r
+                 : cstring_makeLiteral ("<no name>")));\r
+      sfreeEventually (buffer);\r
+      return NULL;\r
+    }\r
+\r
+  llassert (buf != NULL);\r
+\r
+  buf--;\r
+  memset ((char *) buf, 0, sizeof (*buf));\r
+  CPPBUFFER (pfile) = buf;\r
+\r
+  buf->if_stack = pfile->if_stack;\r
+  buf->cleanup = cppReader_nullCleanup;\r
+  buf->underflow = cppReader_nullUnderflow;\r
+  buf->buf = buffer;\r
+  buf->cur = buf->buf;\r
+\r
+  if (buffer != NULL)\r
+    {\r
+      buf->alimit = buf->rlimit = buffer + length;\r
+    }\r
+  else\r
+    {\r
+      buf->alimit = buf->rlimit = NULL;\r
+    }\r
+\r
+  return buf;\r
+}\r
+\r
+cppBuffer *\r
+cppReader_popBuffer (cppReader *pfile)\r
+{\r
+  cppBuffer *buf = CPPBUFFER (pfile);\r
+\r
+  llassert (buf != NULL);\r
+\r
+  (void) (*buf->cleanup) (buf, pfile);\r
+  return ++CPPBUFFER (pfile);\r
+}\r
+\r
+/* Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer.\r
+   Pop the buffer when done.  */\r
+\r
+void\r
+cppReader_scanBuffer (cppReader *pfile)\r
+{\r
+  cppBuffer *buffer = CPPBUFFER (pfile);\r
+  for (;;)\r
+    {\r
+      enum cpp_token token;\r
+      \r
+      token = cppGetToken (pfile);\r
+\r
+      if (token == CPP_EOF) /* Should not happen ...  */\r
+       {\r
+         break;\r
+       }\r
+\r
+      if (token == CPP_POP && CPPBUFFER (pfile) == buffer)\r
+       {\r
+         (void) cppReader_popBuffer (pfile);\r
+         break;\r
+       }\r
+    }\r
+}\r
+\r
+/*\r
+ * Rescan a string (which may have escape marks) into pfile's buffer.\r
+ * Place the result in pfile->token_buffer.\r
+ *\r
+ * The input is copied before it is scanned, so it is safe to pass\r
+ * it something from the token_buffer that will get overwritten\r
+ * (because it follows cppReader_getWritten).  This is used by do_include.\r
+ */\r
+\r
+static void\r
+cpp_expand_to_buffer (cppReader *pfile, char *buf, size_t length)\r
+{\r
+  register cppBuffer *ip;\r
+  char *limit = buf + length;\r
+  char *buf1, *p1, *p2;\r
+\r
+  /* evans - 2001-08-26\r
+  ** length is unsigned - this doesn't make sense\r
+  if (length < 0)\r
+    abort ();\r
+  **\r
+  */\r
+\r
+  /* Set up the input on the input stack.  */\r
+\r
+  buf1 = (char *) dmalloc (length + 1);\r
+\r
+  p1 = buf;\r
+  p2 = buf1;\r
+\r
+  while (p1 != limit)\r
+    {\r
+      *p2++ = *p1++;\r
+    }\r
+\r
+  buf1[length] = '\0';\r
+\r
+  ip = cppReader_pushBuffer (pfile, buf1, length);\r
+\r
+  if (ip == NULL)\r
+    return;\r
+\r
+  ip->has_escapes = TRUE;\r
+\r
+  /* Scan the input, create the output.  */\r
+  cppReader_scanBuffer (pfile);\r
+\r
+  cppReader_nullTerminate (pfile);\r
+}\r
+\r
+static void\r
+adjust_position (char *buf, char *limit, int *linep, int *colp)\r
+{\r
+  while (buf < limit)\r
+    {\r
+      char ch = *buf++;\r
+      if (ch == '\n')\r
+       (*linep)++, (*colp) = 1;\r
+      else\r
+       (*colp)++;\r
+    }\r
+}\r
+\r
+/* Move line_base forward, updating lineno and colno.  */\r
+\r
+static void\r
+update_position (cppBuffer *pbuf)\r
+{\r
+  char *old_pos;\r
+  char *new_pos = pbuf->cur;\r
+  register struct parse_marker *mark;\r
+\r
+  llassert (pbuf->buf != NULL);\r
+  old_pos = pbuf->buf + pbuf->line_base;\r
+\r
+  for (mark = pbuf->marks;  mark != NULL; mark = mark->next)\r
+    {\r
+      if (pbuf->buf + mark->position < new_pos)\r
+       new_pos = pbuf->buf + mark->position;\r
+    }\r
+  pbuf->line_base += new_pos - old_pos;\r
+\r
+  llassert (old_pos != NULL);\r
+  llassert (new_pos != NULL);\r
+\r
+  adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno);\r
+}\r
+\r
+void\r
+cppBuffer_lineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep,\r
+                        /*@null@*/ /*@out@*/ int *colp)\r
+{\r
+  int dummy;\r
+\r
+  if (colp == NULL)\r
+    {\r
+      colp = &dummy;\r
+      /*@-branchstate@*/\r
+    } /*@=branchstate@*/\r
+\r
+  if (pbuf != NULL)\r
+    {\r
+      *linep = pbuf->lineno;\r
+      *colp = pbuf->colno;\r
+\r
+      llassert (pbuf->buf != NULL);\r
+      llassert (pbuf->cur != NULL);\r
+\r
+      adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp);\r
+    }\r
+  else\r
+    {\r
+      *linep = 0;\r
+      *colp = 0;\r
+    }\r
+}\r
+\r
+/* Return the cppBuffer that corresponds to a file (not a macro).  */\r
+\r
+/*@exposed@*/ /*@null@*/ cppBuffer *cppReader_fileBuffer (cppReader *pfile)\r
+{\r
+  cppBuffer *ip = cppReader_getBuffer (pfile);\r
+\r
+  for ( ;\r
+       ip != NULL && ip != cppReader_nullBuffer (pfile); \r
+       ip = cppBuffer_prevBuffer (ip))\r
+    {\r
+      if (ip->fname != NULL)\r
+       {\r
+         return ip;\r
+       }\r
+    }\r
+  \r
+  return NULL;\r
+}\r
+\r
+static long\r
+count_newlines (char *buf, char *limit)\r
+{\r
+  register long count = 0;\r
+\r
+  while (buf < limit)\r
+    {\r
+      char ch = *buf++;\r
+      if (ch == '\n')\r
+       count++;\r
+    }\r
+  return count;\r
+}\r
+\r
+/*\r
+ * write out a #line command, for instance, after an #include file.\r
+ * If CONDITIONAL is nonzero, we can omit the #line if it would\r
+ * appear to be a no-op, and we can output a few newlines instead\r
+ * if we want to increase the line number by a small amount.\r
+ * FILE_CHANGE says whether we are entering a file, leaving, or neither.\r
+ */\r
+\r
+static void\r
+output_line_command (cppReader *pfile, bool conditional,\r
+                    enum file_change_code file_change)\r
+{\r
+  int line, col;\r
+  cppBuffer *ip = CPPBUFFER (pfile);\r
+  cppBuffer *buf;\r
+\r
+  llassert (ip != NULL);\r
+\r
+  if (ip->fname == NULL)\r
+    return;\r
+\r
+  update_position (ip);\r
+\r
+  if (CPPOPTIONS (pfile)->no_line_commands\r
+      || CPPOPTIONS (pfile)->no_output)\r
+    return;\r
+\r
+  buf = CPPBUFFER (pfile);\r
+\r
+  llassert (buf != NULL);\r
+\r
+  line = buf->lineno;\r
+  col = buf->colno;\r
+\r
+  llassert (ip->cur != NULL);\r
+\r
+  adjust_position (cppLineBase (ip), ip->cur, &line, &col);\r
+\r
+  if (CPPOPTIONS (pfile)->no_line_commands)\r
+    return;\r
+\r
+  if (conditional) {\r
+    if (line == pfile->lineno)\r
+      return;\r
+\r
+    /* If the inherited line number is a little too small,\r
+       output some newlines instead of a #line command.  */\r
+\r
+    if (line > pfile->lineno && line < pfile->lineno + 8)\r
+      {\r
+       cppReader_reserve (pfile, 20);\r
+       while (line > pfile->lineno)\r
+         {\r
+           cppReader_putCharQ (pfile, '\n');\r
+           pfile->lineno++;\r
+         }\r
+\r
+       return;\r
+      }\r
+  }\r
+\r
+  cppReader_reserve (pfile,\r
+                    size_fromInt (4 * cstring_length (ip->nominal_fname) + 50));\r
+\r
+  {\r
+#ifdef OUTPUT_LINE_COMMANDS\r
+    static char sharp_line[] = "#line ";\r
+#else\r
+    static char sharp_line[] = "# ";\r
+#endif\r
+    cppReader_putStrN (pfile, sharp_line, sizeof(sharp_line)-1);\r
+  }\r
+\r
+  sprintf (cppReader_getPWritten (pfile), "%d ", line);\r
+  cppReader_adjustWritten (pfile, strlen (cppReader_getPWritten (pfile)));\r
+\r
+  quote_string (pfile, cstring_toCharsSafe (ip->nominal_fname));\r
+\r
+  if (file_change != same_file) {\r
+    cppReader_putCharQ (pfile, ' ');\r
+    cppReader_putCharQ (pfile, file_change == enter_file ? '1' : '2');\r
+  }\r
+  /* Tell cc1 if following text comes from a system header file.  */\r
+  if (ip->system_header_p != '\0') {\r
+    cppReader_putCharQ (pfile, ' ');\r
+    cppReader_putCharQ (pfile, '3');\r
+  }\r
+#ifndef NO_IMPLICIT_EXTERN_C\r
+  /* Tell cc1plus if following text should be treated as C.  */\r
+  if (ip->system_header_p == (char) 2 && CPPOPTIONS (pfile)->cplusplus) {\r
+    cppReader_putCharQ (pfile, ' ');\r
+    cppReader_putCharQ (pfile, '4');\r
+  }\r
+#endif\r
+  cppReader_putCharQ (pfile, '\n');\r
+  pfile->lineno = line;\r
+}\r
+\r
+\r
+/*\r
+ * Parse a macro argument and append the info on PFILE's token_buffer.\r
+ * REST_ARGS means to absorb the rest of the args.\r
+ * Return nonzero to indicate a syntax error.\r
+ */\r
+\r
+static enum cpp_token\r
+macarg (cppReader *pfile, int rest_args)\r
+{\r
+  int paren = 0;\r
+  enum cpp_token token;\r
+  char save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;\r
+  bool oldexpand = pfile->no_macro_expand;\r
+  CPPOPTIONS (pfile)->put_out_comments = 1;\r
+\r
+  /* Try to parse as much of the argument as exists at this\r
+     input stack level.  */\r
+\r
+  pfile->no_macro_expand = TRUE;\r
+\r
+  for (;;)\r
+    {\r
+      token = cppGetToken (pfile);\r
+\r
+      switch (token)\r
+       {\r
+       case CPP_EOF:\r
+         goto done;\r
+       case CPP_POP:\r
+         /* If we've hit end of file, it's an error (reported by caller).\r
+            Ditto if it's the end of cpp_expand_to_buffer text.\r
+            If we've hit end of macro, just continue.  */\r
+         if (!cppBuffer_isMacro (CPPBUFFER (pfile)))\r
+           goto done;\r
+         /*@switchbreak@*/ break;\r
+       case CPP_LPAREN:\r
+         paren++;\r
+         /*@switchbreak@*/ break;\r
+       case CPP_RPAREN:\r
+         if (--paren < 0)\r
+           goto found;\r
+         /*@switchbreak@*/ break;\r
+       case CPP_COMMA:\r
+         /* if we've returned to lowest level and\r
+            we aren't absorbing all args */\r
+         if (paren == 0 && rest_args == 0)\r
+           goto found;\r
+         /*@switchbreak@*/ break;\r
+       found:\r
+         /* Remove ',' or ')' from argument buffer.  */\r
+         cppReader_adjustWritten (pfile, -1);\r
+         goto done;\r
+       default:\r
+         ;\r
+       }\r
+    }\r
+\r
+done:\r
+  CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;\r
+  pfile->no_macro_expand = oldexpand;\r
+\r
+  return token;\r
+}\r
+\r
+\r
+/* Turn newlines to spaces in the string of length LENGTH at START,\r
+   except inside of string constants.\r
+   The string is copied into itself with its beginning staying fixed.  */\r
+\r
+static int\r
+change_newlines (char *start, int length)\r
+{\r
+  register char *ibp;\r
+  register char *obp;\r
+  register char *limit;\r
+  char c;\r
+\r
+  ibp = start;\r
+  limit = start + length;\r
+  obp = start;\r
+\r
+  while (ibp < limit) {\r
+    *obp++ = c = *ibp++;\r
+    switch (c) {\r
+\r
+    case '\'':\r
+    case '\"':\r
+      /* Notice and skip strings, so that we don't delete newlines in them.  */\r
+      {\r
+       char quotec = c;\r
+       while (ibp < limit) {\r
+         *obp++ = c = *ibp++;\r
+         if (c == quotec)\r
+           /*@innerbreak@*/ break;\r
+         if (c == '\n' && quotec == '\'')\r
+           /*@innerbreak@*/ break;\r
+       }\r
+      }\r
+    /*@switchbreak@*/ break;\r
+    }\r
+  }\r
+\r
+  return obp - start;\r
+}\r
+\r
+static /*@observer@*/ struct tm *\r
+timestamp (/*@returned@*/ cppReader *pfile)\r
+{\r
+  if (pfile->timebuf == NULL)\r
+    {\r
+      time_t t = time ((time_t *) 0);\r
+      pfile->timebuf = localtime (&t);\r
+    }\r
+\r
+  llassert (pfile->timebuf != NULL);\r
+\r
+  return pfile->timebuf;\r
+}\r
+\r
+static ob_mstring monthnames[] = {\r
+  "Jan", "Feb", "Mar", "Apr", "May", "Jun",\r
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",\r
+} ;\r
+\r
+/*\r
+ * expand things like __FILE__.  Place the expansion into the output\r
+ * buffer *without* rescanning.\r
+ */\r
+\r
+static void\r
+special_symbol (hashNode hp, cppReader *pfile)\r
+{\r
+  cstring buf = cstring_undefined;\r
+  size_t len;\r
+  int true_indepth;\r
+  cppBuffer *ip;\r
+  struct tm *timebuf;\r
+\r
+  int paren = 0;               /* For special `defined' keyword */\r
+\r
+  for (ip = cppReader_getBuffer (pfile); ip != NULL; ip = cppBuffer_prevBuffer (ip))\r
+    {\r
+      if (ip == cppReader_nullBuffer (pfile))\r
+       {\r
+         cppReader_errorLit (pfile,\r
+                       cstring_makeLiteralTemp ("cccp error: not in any file?!"));\r
+         return;                       /* the show must go on */\r
+       }\r
+\r
+      if (ip != NULL && ip->fname != NULL)\r
+       {\r
+         break;\r
+       }\r
+    }\r
+\r
+  switch (hp->type)\r
+    {\r
+    case T_FILE:\r
+    case T_BASE_FILE:\r
+      {\r
+       char *string;\r
+       if (hp->type == T_BASE_FILE)\r
+         {\r
+           while (cppBuffer_prevBuffer (ip) != cppReader_nullBuffer (pfile))\r
+             {\r
+               ip = cppBuffer_prevBuffer (ip);\r
+             }\r
+         }\r
+\r
+       llassert (ip != NULL);\r
+       string = cstring_toCharsSafe (ip->nominal_fname);\r
+\r
+       if (string == NULL)\r
+         {\r
+           string = "";\r
+         }\r
+\r
+       cppReader_reserve (pfile, 3 + 4 * strlen (string));\r
+       quote_string (pfile, string);\r
+       return;\r
+      }\r
+\r
+    case T_INCLUDE_LEVEL:\r
+      true_indepth = 0;\r
+      ip = cppReader_getBuffer (pfile);\r
+\r
+      for (;  ip != cppReader_nullBuffer (pfile) && ip != NULL;\r
+          ip = cppBuffer_prevBuffer (ip))\r
+       {\r
+         if (ip != NULL && ip->fname != NULL)\r
+           {\r
+             true_indepth++;\r
+           }\r
+       }\r
+\r
+      buf = message ("%d", true_indepth - 1);\r
+      break;\r
+\r
+    case T_VERSION:\r
+      buf = message ("\"%s\"", cstring_makeLiteralTemp (CPP_VERSION));\r
+      break;\r
+\r
+#ifndef NO_BUILTIN_SIZE_TYPE\r
+    case T_SIZE_TYPE:\r
+      buf = cstring_makeLiteral (SIZE_TYPE);\r
+      break;\r
+#endif\r
+\r
+#ifndef NO_BUILTIN_PTRDIFF_TYPE\r
+    case T_PTRDIFF_TYPE:\r
+      buf = cstring_makeLiteral (PTRDIFF_TYPE);\r
+      break;\r
+#endif\r
+\r
+    case T_WCHAR_TYPE:\r
+      buf = cstring_makeLiteral (cppReader_wcharType (pfile));\r
+      break;\r
+\r
+    case T_USER_LABEL_PREFIX_TYPE:\r
+      buf = cstring_makeLiteral (USER_LABEL_PREFIX);\r
+      break;\r
+\r
+    case T_REGISTER_PREFIX_TYPE:\r
+      buf = cstring_makeLiteral (REGISTER_PREFIX);\r
+      break;\r
+\r
+    case T_CONST:\r
+      buf = message ("%d", hp->value.ival);\r
+      break;\r
+\r
+    case T_SPECLINE:\r
+      {\r
+       if (ip != NULL)\r
+         {\r
+           int line = ip->lineno;\r
+           int col = ip->colno;\r
+\r
+           llassert (ip->cur != NULL);\r
+           adjust_position (cppLineBase (ip), ip->cur, &line, &col);\r
+\r
+           buf = message ("%d", (int) line);\r
+         }\r
+       else\r
+         {\r
+           BADBRANCH;\r
+         }\r
+      }\r
+    break;\r
+\r
+    case T_DATE:\r
+    case T_TIME:\r
+      {\r
+       char *sbuf = (char *) dmalloc (20);\r
+       timebuf = timestamp (pfile);\r
+       if (hp->type == T_DATE)\r
+         {\r
+           sprintf (sbuf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],\r
+                    timebuf->tm_mday, timebuf->tm_year + 1900);\r
+         }\r
+       else\r
+         {\r
+           sprintf (sbuf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,\r
+                    timebuf->tm_sec);\r
+         }\r
+\r
+       buf = cstring_fromCharsNew (sbuf);\r
+       sfree (sbuf);\r
+       break;\r
+      }\r
+\r
+    case T_SPEC_DEFINED:\r
+      buf = cstring_makeLiteral (" 0 ");     /* Assume symbol is not defined */\r
+      ip = cppReader_getBuffer (pfile);\r
+\r
+      llassert (ip->cur != NULL);\r
+      SKIP_WHITE_SPACE (ip->cur);\r
+\r
+      if (*ip->cur == '(')\r
+       {\r
+         paren++;\r
+         ip->cur++;                    /* Skip over the paren */\r
+         SKIP_WHITE_SPACE (ip->cur);\r
+       }\r
+\r
+      if (!is_idstart[(int) *ip->cur])\r
+       goto oops;\r
+      if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))\r
+       goto oops;\r
+\r
+      if ((hp = cppReader_lookup (ip->cur, -1, -1)) != 0)\r
+       {\r
+         cstring_free (buf);\r
+         buf = cstring_makeLiteral (" 1 ");\r
+       }\r
+\r
+      while (is_idchar[(int) *ip->cur])\r
+       {\r
+         ++ip->cur;\r
+       }\r
+\r
+      SKIP_WHITE_SPACE (ip->cur);\r
+\r
+      if (paren != 0)\r
+       {\r
+         if (*ip->cur != ')')\r
+           goto oops;\r
+         ++ip->cur;\r
+       }\r
+      break;\r
+\r
+    oops:\r
+\r
+      cppReader_errorLit (pfile,\r
+                   cstring_makeLiteralTemp ("`defined' without an identifier"));\r
+      break;\r
+\r
+    default:\r
+      cpp_setLocation (pfile);\r
+      llfatalerror (message ("Pre-processing error: invalid special hash type"));\r
+    }\r
+\r
+  len = size_fromInt (cstring_length (buf));\r
+\r
+  cppReader_reserve (pfile, len + 1);\r
+  cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len);\r
+  cppReader_nullTerminateQ (pfile);\r
+\r
+  cstring_free (buf);\r
+  return;\r
+}\r
+\r
+/* Write out a #define command for the special named MACRO_NAME\r
+   to PFILE's token_buffer.  */\r
+\r
+static void\r
+dump_special_to_buffer (cppReader *pfile, char *macro_name)\r
+{\r
+  static char define_directive[] = "#define ";\r
+  size_t macro_name_length = strlen (macro_name);\r
+  output_line_command (pfile, 0, same_file);\r
+  cppReader_reserve (pfile, sizeof(define_directive) + macro_name_length);\r
+  cppReader_putStrN (pfile, define_directive, sizeof(define_directive)-1);\r
+  cppReader_putStrN (pfile, macro_name, macro_name_length);\r
+  cppReader_putCharQ (pfile, ' ');\r
+  cpp_expand_to_buffer (pfile, macro_name, macro_name_length);\r
+  cppReader_putChar (pfile, '\n');\r
+}\r
+\r
+/* Initialize the built-in macros.  */\r
+\r
+static void\r
+cppReader_installBuiltin (/*@observer@*/ char *name, ctype ctyp,\r
+                         int len, enum node_type type,\r
+                         int ivalue, /*@null@*/ /*@only@*/ char *value,\r
+                         int hash)\r
+{\r
+  cstring sname = cstring_fromCharsNew (name);\r
+\r
+  llassert (usymtab_inGlobalScope ());\r
+\r
+  /*\r
+  ** Be careful here: this is done before the ctype table has\r
+  ** been initialized.\r
+  */\r
+\r
+  if (!usymtab_exists (sname))\r
+    {\r
+      uentry ue = uentry_makeConstant (sname, ctyp, fileloc_createBuiltin ());\r
+\r
+      if (ctype_equal (ctyp, ctype_string))\r
+       {\r
+         qualList ql = qualList_new ();\r
+         ql = qualList_add (ql, qual_createObserver ());\r
+         uentry_reflectQualifiers (ue, ql);\r
+         qualList_free (ql);\r
+       }\r
+      \r
+      usymtab_addGlobalEntry (ue);\r
+    }\r
+  else\r
+    {\r
+      ;\r
+    }\r
+\r
+  (void) cppReader_install (name, len, type, ivalue, value, hash);\r
+  cstring_free (sname);\r
+}\r
+\r
+static void\r
+cppReader_installBuiltinType (/*@observer@*/ char *name, ctype ctyp,\r
+                             int len, enum node_type type,\r
+                             int ivalue,\r
+                             /*@only@*/ /*@null@*/ char *value, int hash)\r
+{\r
+  cstring sname = cstring_fromChars (name);\r
+  /* evs 2000 07 10 - removed a memory leak, detected by lclint */\r
+\r
+  llassert (usymtab_inGlobalScope ());\r
+\r
+  if (!usymtab_existsTypeEither (sname))\r
+    {\r
+      uentry ue = uentry_makeDatatype (sname, ctyp,\r
+                                      NO, NO,\r
+                                      fileloc_createBuiltin ());\r
+      llassert (!usymtab_existsEither (sname));\r
+      usymtab_addGlobalEntry (ue);\r
+    }\r
+\r
+  (void) cppReader_install (name, len, type, ivalue, value, hash);\r
+}\r
+\r
+static void\r
+initialize_builtins (cppReader *pfile)\r
+{\r
+  cppReader_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1);\r
+  cppReader_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1);\r
+  cppReader_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1);\r
+  cppReader_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1);\r
+  cppReader_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1);\r
+  cppReader_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1);\r
+#ifndef NO_BUILTIN_SIZE_TYPE\r
+  cppReader_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1);\r
+#endif\r
+#ifndef NO_BUILTIN_PTRDIFF_TYPE\r
+  cppReader_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1);\r
+#endif\r
+  cppReader_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1);\r
+  cppReader_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1);\r
+  cppReader_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1);\r
+  cppReader_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1);\r
+\r
+  /*\r
+  ** No, don't define __STDC__\r
+  **\r
+\r
+  if (!cppReader_isTraditional (pfile))\r
+    {\r
+      cppReader_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);\r
+    }\r
+\r
+  **\r
+  */\r
+\r
+# ifdef WIN32\r
+    cppReader_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);\r
+# endif\r
+\r
+  /*\r
+  ** This is supplied using a -D by the compiler driver\r
+  ** so that it is present only when truly compiling with GNU C.\r
+  */\r
+\r
+  /*  cppReader_install ("__GNUC__", -1, T_CONST, 2, 0, -1);  */\r
+\r
+  cppReader_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1);\r
+\r
+  if (CPPOPTIONS (pfile)->debug_output)\r
+    {\r
+      dump_special_to_buffer (pfile, "__BASE_FILE__");\r
+      dump_special_to_buffer (pfile, "__VERSION__");\r
+#ifndef NO_BUILTIN_SIZE_TYPE\r
+      dump_special_to_buffer (pfile, "__SIZE_TYPE__");\r
+#endif\r
+#ifndef NO_BUILTIN_PTRDIFF_TYPE\r
+      dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");\r
+#endif\r
+      dump_special_to_buffer (pfile, "__WCHAR_TYPE__");\r
+      dump_special_to_buffer (pfile, "__DATE__");\r
+      dump_special_to_buffer (pfile, "__TIME__");\r
+      if (!cppReader_isTraditional (pfile))\r
+       dump_special_to_buffer (pfile, "__STDC__");\r
+    }\r
+}\r
+\r
+\r
+/* Return 1 iff a token ending in C1 followed directly by a token C2\r
+   could cause mis-tokenization.  */\r
+\r
+static bool\r
+unsafe_chars (char c1, char c2)\r
+{\r
+  switch (c1)\r
+    {\r
+    case '+': case '-':\r
+      if (c2 == c1 || c2 == '=')\r
+       return 1;\r
+      goto letter;\r
+    case '.':\r
+    case '0': case '1': case '2': case '3': case '4':\r
+    case '5': case '6': case '7': case '8': case '9':\r
+    case 'e': case 'E': case 'p': case 'P':\r
+      if (c2 == '-' || c2 == '+')\r
+       return 1; /* could extend a pre-processing number */\r
+      goto letter;\r
+    case 'L':\r
+      if (c2 == '\'' || c2 == '\"')\r
+       return 1;   /* Could turn into L"xxx" or L'xxx'.  */\r
+      goto letter;\r
+    letter:\r
+    case '_':\r
+    case 'a': case 'b': case 'c': case 'd':           case 'f':\r
+    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':\r
+    case 'm': case 'n': case 'o':           case 'q': case 'r':\r
+    case 's': case 't': case 'u': case 'v': case 'w': case 'x':\r
+    case 'y': case 'z':\r
+    case 'A': case 'B': case 'C': case 'D':           case 'F':\r
+    case 'G': case 'H': case 'I': case 'J': case 'K':\r
+    case 'M': case 'N': case 'O':           case 'Q': case 'R':\r
+    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\r
+    case 'Y': case 'Z':\r
+      /* We're in the middle of either a name or a pre-processing number.  */\r
+      return (is_idchar[(int) c2] || c2 == '.');\r
+    case '<': case '>': case '!': case '%': case '#': case ':':\r
+    case '^': case '&': case '|': case '*': case '/': case '=':\r
+      return (c2 == c1 || c2 == '=');\r
+    }\r
+  return 0;\r
+}\r
+\r
+/* Expand a macro call.\r
+   HP points to the symbol that is the macro being called.\r
+   Put the result of expansion onto the input stack\r
+   so that subsequent input by our caller will use it.\r
+\r
+   If macro wants arguments, caller has already verified that\r
+   an argument list follows; arguments come from the input stack.  */\r
+\r
+static void\r
+macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)\r
+{\r
+  int nargs;\r
+  DEFINITION *defn = hp->value.defn;\r
+  char *xbuf;\r
+  char *oxbuf = NULL;\r
+  int start_line;\r
+  int start_column;\r
+  size_t xbuf_len;\r
+  size_t old_written = cppReader_getWritten (pfile);\r
+  int rest_args;\r
+  int rest_zero = 0;\r
+  int i;\r
+  struct argdata *args = NULL;\r
+\r
+  pfile->output_escapes++;\r
+\r
+  cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);\r
+\r
+  nargs = defn->nargs;\r
+\r
+  if (nargs >= 0)\r
+    {\r
+      enum cpp_token token = CPP_EOF;\r
+\r
+      args = (struct argdata *) dmalloc ((nargs + 1) * sizeof (*args));\r
+\r
+      for (i = 0; i < nargs; i++)\r
+       {\r
+         args[i].expanded = 0;\r
+         args[i].raw = 0;\r
+         args[i].raw_length = 0;\r
+         args[i].expand_length = args[i].stringified_length = -1;\r
+         args[i].use_count = 0;\r
+       }\r
+\r
+      /*\r
+      ** Parse all the macro args that are supplied.  I counts them.\r
+      ** The first NARGS args are stored in ARGS.\r
+      ** The rest are discarded.  If rest_args is set then we assume\r
+      ** macarg absorbed the rest of the args.\r
+      */\r
+\r
+      i = 0;\r
+      rest_args = 0;\r
+\r
+      cppReader_forward (pfile, 1); /* Discard the open-parenthesis before the first arg.  */\r
+      do\r
+       {\r
+         if (rest_args != 0)\r
+           {\r
+             continue;\r
+           }\r
+\r
+         if (i < nargs || (nargs == 0 && i == 0))\r
+           {\r
+             /* if we are working on last arg which absorbs rest of args... */\r
+             if (i == nargs - 1 && defn->rest_args)\r
+               {\r
+                 rest_args = 1;\r
+               }\r
+\r
+             args[i].raw = size_toLong (cppReader_getWritten (pfile));\r
+             token = macarg (pfile, rest_args);\r
+             args[i].raw_length = cppReader_getWritten (pfile) - args[i].raw;\r
+             args[i].newlines = FALSE; /* FIXME */\r
+           }\r
+         else\r
+           {\r
+             token = macarg (pfile, 0);\r
+           }\r
+\r
+         if (token == CPP_EOF || token == CPP_POP)\r
+           {\r
+             cppReader_errorWithLine (pfile, start_line, start_column,\r
+                                  cstring_fromCharsNew ("unterminated macro call"));\r
+             sfree (args);\r
+             return;\r
+           }\r
+         i++;\r
+       } while (token == CPP_COMMA);\r
+\r
+      /* If we got one arg but it was just whitespace, call that 0 args.  */\r
+      if (i == 1)\r
+       {\r
+         char *bp;\r
+         char *lim;\r
+\r
+         assertSet (args);\r
+\r
+         bp = ARG_BASE + args[0].raw;\r
+         lim = bp + args[0].raw_length;\r
+\r
+         /* cpp.texi says for foo ( ) we provide one argument.\r
+            However, if foo wants just 0 arguments, treat this as 0.  */\r
+\r
+         if (nargs == 0)\r
+           {\r
+             while (bp != lim && is_space[(int) *bp])\r
+               {\r
+                 bp++;\r
+               }\r
+           }\r
+\r
+         if (bp == lim)\r
+           i = 0;\r
+       }\r
+\r
+      /* Don't output an error message if we have already output one for\r
+        a parse error above.  */\r
+      rest_zero = 0;\r
+\r
+      if (nargs == 0 && i > 0)\r
+       {\r
+         cppReader_error (pfile,\r
+                    message ("arguments given to macro `%s'", hp->name));\r
+       }\r
+      else if (i < nargs)\r
+       {\r
+         /* traditional C allows foo() if foo wants one argument.  */\r
+         if (nargs == 1 && i == 0 && cppReader_isTraditional (pfile))\r
+           {\r
+             ;\r
+           }\r
+         /* the rest args token is allowed to absorb 0 tokens */\r
+         else if (i == nargs - 1 && defn->rest_args)\r
+           rest_zero = 1;\r
+         else if (i == 0)\r
+           cppReader_error (pfile,\r
+                      message ("macro `%s' used without args", hp->name));\r
+         else if (i == 1)\r
+           cppReader_error (pfile,\r
+                      message ("macro `%s' used with just one arg", hp->name));\r
+         else\r
+           {\r
+             cppReader_error (pfile,\r
+                        message ("macro `%s' used with only %d args",\r
+                                 hp->name, i));\r
+           }\r
+       }\r
+      else if (i > nargs)\r
+       {\r
+         cppReader_error (pfile,\r
+                    message ("macro `%s' used with too many (%d) args", hp->name, i));\r
+       }\r
+      else\r
+       {\r
+         ;\r
+       }\r
+    }\r
+\r
+  /* If macro wants zero args, we parsed the arglist for checking only.\r
+     Read directly from the macro definition.  */\r
+\r
+  if (nargs <= 0)\r
+    {\r
+      xbuf = defn->expansion;\r
+      xbuf_len = defn->length;\r
+    }\r
+  else\r
+    {\r
+      char *exp = defn->expansion;\r
+      int offset;      /* offset in expansion,\r
+                                  copied a piece at a time */\r
+      size_t totlen;   /* total amount of exp buffer filled so far */\r
+\r
+      register struct reflist *ap, *last_ap;\r
+      \r
+      assertSet (args); /* args is defined since the nargs > 0 path was taken */\r
+\r
+      /* Macro really takes args.  Compute the expansion of this call.  */\r
+\r
+      /* Compute length in characters of the macro's expansion.\r
+        Also count number of times each arg is used.  */\r
+      xbuf_len = defn->length;\r
+\r
+      llassert (args != NULL);\r
+\r
+      for (ap = defn->pattern; ap != NULL; ap = ap->next)\r
+       {\r
+         if (ap->stringify)\r
+           {\r
+             struct argdata *arg = &args[ap->argno];\r
+\r
+             /* Stringify it it hasn't already been */\r
+             assertSet (arg);\r
+\r
+             if (arg->stringified_length < 0)\r
+               {\r
+                 int arglen = arg->raw_length;\r
+                 bool escaped = FALSE;\r
+                 char in_string = '\0';\r
+                 char c;\r
+\r
+                 /* Initially need_space is -1.  Otherwise, 1 means the\r
+                    previous character was a space, but we suppressed it;\r
+                    0 means the previous character was a non-space.  */\r
+                 int need_space = -1;\r
+\r
+                 i = 0;\r
+                 arg->stringified = cppReader_getWritten (pfile);\r
+                 if (!cppReader_isTraditional (pfile))\r
+                   cppReader_putChar (pfile, '\"'); /* insert beginning quote */\r
+                 for (; i < arglen; i++)\r
+                   {\r
+                     c = (ARG_BASE + arg->raw)[i];\r
+\r
+                     if (in_string == '\0')\r
+                       {\r
+                         /* Internal sequences of whitespace are replaced by\r
+                            one space except within an string or char token.*/\r
+                         if (is_space[(int) c])\r
+                           {\r
+                             if (cppReader_getWritten (pfile) > arg->stringified\r
+                                 && (cppReader_getPWritten (pfile))[-1] == '@')\r
+                               {\r
+                                 /* "@ " escape markers are removed */\r
+                                 cppReader_adjustWritten (pfile, -1);\r
+                                 /*@innercontinue@*/ continue;\r
+                               }\r
+                             if (need_space == 0)\r
+                               need_space = 1;\r
+                             /*@innercontinue@*/ continue;\r
+                           }\r
+                         else if (need_space > 0)\r
+                           cppReader_putChar (pfile, ' ');\r
+                         else\r
+                           {\r
+                             ;\r
+                           }\r
+\r
+                         need_space = 0;\r
+                       }\r
+\r
+                     if (escaped)\r
+                       escaped = 0;\r
+                     else\r
+                       {\r
+                         if (c == '\\')\r
+                           escaped = 1;\r
+\r
+                         if (in_string != '\0')\r
+                           {\r
+                             if (c == in_string)\r
+                               in_string = '\0';\r
+                           }\r
+                         else if (c == '\"' || c == '\'')\r
+                           {\r
+                             in_string = c;\r
+                           }\r
+                         else\r
+                           {\r
+                             ;\r
+                           }\r
+                       }\r
+\r
+                     /* Escape these chars */\r
+                     if (c == '\"' || (in_string != '\0' && c == '\\'))\r
+                       cppReader_putChar (pfile, '\\');\r
+                     if (isprint (c))\r
+                       cppReader_putChar (pfile, c);\r
+                     else\r
+                       {\r
+                         cppReader_reserve (pfile, 4);\r
+                         sprintf (cppReader_getPWritten (pfile), "\\%03o",\r
+                                  (unsigned int) c);\r
+                         cppReader_adjustWritten (pfile, 4);\r
+                       }\r
+                   }\r
+                 if (!cppReader_isTraditional (pfile))\r
+                   cppReader_putChar (pfile, '\"'); /* insert ending quote */\r
+                 arg->stringified_length\r
+                   = size_toInt (cppReader_getWritten (pfile) - arg->stringified);\r
+               }\r
+\r
+             xbuf_len += args[ap->argno].stringified_length;\r
+           }\r
+         else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))\r
+           {\r
+             /* Add 4 for two newline-space markers to prevent\r
+                token concatenation.  */\r
+             assertSet (args); /*@i534 shouldn't need this */\r
+             xbuf_len += args[ap->argno].raw_length + 4;\r
+           }\r
+         else\r
+           {\r
+             /* We have an ordinary (expanded) occurrence of the arg.\r
+                So compute its expansion, if we have not already.  */\r
+\r
+             assertSet (args); /*@i534 shouldn't need this */\r
+\r
+             if (args[ap->argno].expand_length < 0)\r
+               {\r
+                 args[ap->argno].expanded = cppReader_getWritten (pfile);\r
+                 cpp_expand_to_buffer (pfile,\r
+                                       ARG_BASE + args[ap->argno].raw,\r
+                                       size_fromInt (args[ap->argno].raw_length));\r
+\r
+                 args[ap->argno].expand_length\r
+                   = size_toInt (cppReader_getWritten (pfile) - args[ap->argno].expanded);\r
+               }\r
+\r
+             /* Add 4 for two newline-space markers to prevent\r
+                token concatenation.  */\r
+             xbuf_len += args[ap->argno].expand_length + 4;\r
+          }\r
+         if (args[ap->argno].use_count < 10)\r
+           args[ap->argno].use_count++;\r
+       }\r
+\r
+      xbuf = (char *) dmalloc (xbuf_len + 1);\r
+      oxbuf = xbuf;\r
+\r
+      /*\r
+      ** Generate in XBUF the complete expansion\r
+      ** with arguments substituted in.\r
+      ** TOTLEN is the total size generated so far.\r
+      ** OFFSET is the index in the definition\r
+      ** of where we are copying from.\r
+      */\r
+\r
+      offset = 0;\r
+      totlen = 0;\r
+\r
+      for (last_ap = NULL, ap = defn->pattern; ap != NULL;\r
+          last_ap = ap, ap = ap->next)\r
+       {\r
+         register struct argdata *arg = &args[ap->argno];\r
+         size_t count_before = totlen;\r
+\r
+         /* Add chars to XBUF.  */\r
+         for (i = 0; i < ap->nchars; i++, offset++)\r
+           {\r
+             xbuf[totlen++] = exp[offset];\r
+           }\r
+\r
+         /* If followed by an empty rest arg with concatenation,\r
+            delete the last run of nonwhite chars.  */\r
+         if (rest_zero && totlen > count_before\r
+             && ((ap->rest_args && ap->raw_before)\r
+                 || (last_ap != NULL && last_ap->rest_args\r
+                     && last_ap->raw_after)))\r
+           {\r
+             /* Delete final whitespace.  */\r
+             while (totlen > count_before && is_space[(int) xbuf[totlen - 1]])\r
+               {\r
+                 totlen--;\r
+               }\r
+\r
+             /* Delete the nonwhites before them.  */\r
+             while (totlen > count_before && ! is_space[(int) xbuf[totlen - 1]])\r
+               {\r
+                 totlen--;\r
+               }\r
+           }\r
+\r
+         if (ap->stringify != 0)\r
+           {\r
+             assertSet(arg);\r
+             memcpy (xbuf + totlen,\r
+                     ARG_BASE + arg->stringified,\r
+                     size_fromInt (arg->stringified_length));\r
+             totlen += arg->stringified_length;\r
+           }\r
+         else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))\r
+           {\r
+             char *p1;\r
+             char *l1;\r
+\r
+             assertSet (arg);\r
+\r
+             p1 = ARG_BASE + arg->raw;\r
+             l1 = p1 + arg->raw_length;\r
+\r
+             if (ap->raw_before)\r
+               {\r
+                 while (p1 != l1 && is_space[(int) *p1])\r
+                   {\r
+                     p1++;\r
+                   }\r
+\r
+                 while (p1 != l1 && is_idchar[(int) *p1])\r
+                   {\r
+                     xbuf[totlen++] = *p1++;\r
+                   }\r
+\r
+                 /* Delete any no-reexpansion marker that follows\r
+                    an identifier at the beginning of the argument\r
+                    if the argument is concatenated with what precedes it.  */\r
+                 if (p1[0] == '@' && p1[1] == '-')\r
+                   p1 += 2;\r
+               }\r
+             if (ap->raw_after)\r
+               {\r
+                 /* Arg is concatenated after: delete trailing whitespace,\r
+                    whitespace markers, and no-reexpansion markers.  */\r
+                 while (p1 != l1)\r
+                   {\r
+                     if (is_space[(int) l1[-1]]) l1--;\r
+                     else if (l1[-1] == '-')\r
+                       {\r
+                         char *p2 = l1 - 1;\r
+                         /* If a `-' is preceded by an odd number of newlines then it\r
+                            and the last newline are a no-reexpansion marker.  */\r
+                         while (p2 != p1 && p2[-1] == '\n')\r
+                           {\r
+                             p2--;\r
+                           }\r
+\r
+                         if (((l1 - 1 - p2) & 1) != 0)\r
+                           {\r
+                             l1 -= 2;\r
+                           }\r
+                         else\r
+                           {\r
+                             /*@innerbreak@*/ break;\r
+                           }\r
+                       }\r
+                     else\r
+                       {\r
+                         /*@innerbreak@*/ break;\r
+                       }\r
+                   }\r
+               }\r
+\r
+             memcpy (xbuf + totlen, p1, size_fromInt (l1 - p1));\r
+             totlen += l1 - p1;\r
+           }\r
+         else\r
+           {\r
+             char *expanded;\r
+\r
+             assertSet (arg);\r
+             expanded = ARG_BASE + arg->expanded;\r
+\r
+             if (!ap->raw_before && totlen > 0\r
+                 && (arg->expand_length != 0)\r
+                 && !cppReader_isTraditional(pfile)\r
+                 && unsafe_chars (xbuf[totlen-1], expanded[0]))\r
+               {\r
+                 xbuf[totlen++] = '@';\r
+                 xbuf[totlen++] = ' ';\r
+               }\r
+\r
+             memcpy (xbuf + totlen, expanded,\r
+                     size_fromInt (arg->expand_length));\r
+             totlen += arg->expand_length;\r
+\r
+             if (!ap->raw_after && totlen > 0\r
+                 && offset < size_toInt (defn->length)\r
+                 && !cppReader_isTraditional(pfile)\r
+                 && unsafe_chars (xbuf[totlen-1], exp[offset]))\r
+               {\r
+                 xbuf[totlen++] = '@';\r
+                 xbuf[totlen++] = ' ';\r
+               }\r
+\r
+             /* If a macro argument with newlines is used multiple times,\r
+                then only expand the newlines once.  This avoids creating\r
+                output lines which don't correspond to any input line,\r
+                which confuses gdb and gcov.  */\r
+             if (arg->use_count > 1 && arg->newlines > 0)\r
+               {\r
+                 /* Don't bother doing change_newlines for subsequent\r
+                    uses of arg.  */\r
+                 arg->use_count = 1;\r
+                 arg->expand_length\r
+                   = change_newlines (expanded, arg->expand_length);\r
+               }\r
+           }\r
+\r
+         if (totlen > xbuf_len)\r
+           abort ();\r
+       }\r
+\r
+      /* if there is anything left of the definition\r
+        after handling the arg list, copy that in too.  */\r
+\r
+      for (i = offset; i < size_toInt (defn->length); i++)\r
+       {\r
+         /* if we've reached the end of the macro */\r
+         if (exp[i] == ')')\r
+           rest_zero = 0;\r
+         if (! (rest_zero && last_ap != NULL && last_ap->rest_args\r
+                && last_ap->raw_after))\r
+           xbuf[totlen++] = exp[i];\r
+       }\r
+\r
+      xbuf[totlen] = '\0';\r
+      xbuf_len = totlen;\r
+    }\r
+\r
+  pfile->output_escapes--;\r
+\r
+  /* Now put the expansion on the input stack\r
+     so our caller will commence reading from it.  */\r
+  push_macro_expansion (pfile, xbuf, xbuf_len, hp);\r
+  cppReader_getBuffer (pfile)->has_escapes = 1;\r
+\r
+  /* Pop the space we've used in the token_buffer for argument expansion.  */\r
+  cppReader_setWritten (pfile, old_written);\r
+\r
+  /* Recursive macro use sometimes works traditionally.\r
+     #define foo(x,y) bar (x (y,0), y)\r
+     foo (foo, baz)  */\r
+\r
+  if (!cppReader_isTraditional (pfile))\r
+    hp->type = T_DISABLED;\r
+\r
+  sfree (args);\r
+}\r
+\r
+static void\r
+push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,\r
+                     /*@dependent@*/ hashNode hp)\r
+{\r
+  cppBuffer *mbuf = cppReader_pushBuffer (pfile, xbuf, xbuf_len);\r
+\r
+  if (mbuf == NULL)\r
+    {\r
+      return;\r
+    }\r
+\r
+  mbuf->cleanup = cppReader_macroCleanup;\r
+\r
+  llassert (mbuf->hnode == NULL);\r
+  mbuf->hnode = hp;\r
+\r
+  /* The first chars of the expansion should be a "@ " added by\r
+     collect_expansion.  This is to prevent accidental token-pasting\r
+     between the text preceding the macro invocation, and the macro\r
+     expansion text.\r
+\r
+     We would like to avoid adding unneeded spaces (for the sake of\r
+     tools that use cpp, such as imake).  In some common cases we can\r
+     tell that it is safe to omit the space.\r
+\r
+     The character before the macro invocation cannot have been an\r
+     idchar (or else it would have been pasted with the idchars of\r
+     the macro name).  Therefore, if the first non-space character\r
+     of the expansion is an idchar, we do not need the extra space\r
+     to prevent token pasting.\r
+\r
+     Also, we don't need the extra space if the first char is '(',\r
+     or some other (less common) characters.  */\r
+\r
+  if (xbuf[0] == '@' && xbuf[1] == ' '\r
+      && (is_idchar[(int) xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''\r
+         || xbuf[2] == '\"'))\r
+  {\r
+    llassert (mbuf->cur != NULL);\r
+    mbuf->cur += 2;\r
+  }\r
+}\r
+\r
+\r
+/* Like cppGetToken, except that it does not read past end-of-line.\r
+   Also, horizontal space is skipped, and macros are popped.  */\r
+\r
+static enum cpp_token\r
+get_directive_token (cppReader *pfile)\r
+{\r
+  for (;;)\r
+    {\r
+      size_t old_written = cppReader_getWritten (pfile);\r
+      enum cpp_token token;\r
+      cppSkipHspace (pfile);\r
+      if (cppReader_peekC (pfile) == '\n')\r
+       {\r
+         return CPP_VSPACE;\r
+       }\r
+\r
+      token = cppGetToken (pfile);\r
+\r
+      switch (token)\r
+       {\r
+       case CPP_POP:\r
+         if (!cppBuffer_isMacro (cppReader_getBuffer (pfile)))\r
+           return token;\r
+         /*@fallthrough@*/\r
+       case CPP_HSPACE:\r
+       case CPP_COMMENT:\r
+         cppReader_setWritten (pfile, old_written);\r
+         /*@switchbreak@*/ break;\r
+       default:\r
+         return token;\r
+       }\r
+    }\r
+}\r
+\r
+\r
+/* Handle #include and #import.\r
+   This function expects to see "fname" or <fname> on the input.\r
+\r
+   The input is normally in part of the output_buffer following\r
+   cppReader_getWritten, and will get overwritten by output_line_command.\r
+   I.e. in input file specification has been popped by cppReader_handleDirective.\r
+   This is safe.  */\r
+\r
+static int\r
+do_include (cppReader *pfile, struct directive *keyword,\r
+           /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)\r
+{\r
+  bool skip_dirs = (keyword->type == T_INCLUDE_NEXT);\r
+  cstring fname;\r
+  char *fbeg, *fend;           /* Beginning and end of fname */\r
+  enum cpp_token token;\r
+\r
+  /* Chain of dirs to search */\r
+  struct file_name_list *search_start = CPPOPTIONS (pfile)->include;\r
+  struct file_name_list dsp[1];        /* First in chain, if #include "..." */\r
+  struct file_name_list *searchptr = NULL;\r
+  size_t old_written = cppReader_getWritten (pfile);\r
+\r
+  int flen;\r
+\r
+  int f;                       /* file number */\r
+  int angle_brackets = 0;      /* 0 for "...", 1 for <...> */\r
+  f= -1;                       /* JF we iz paranoid! */\r
+\r
+  pfile->parsing_include_directive++;\r
+  token = get_directive_token (pfile);\r
+  pfile->parsing_include_directive--;\r
+\r
+  if (token == CPP_STRING)\r
+    {\r
+      /* FIXME - check no trailing garbage */\r
+      fbeg = pfile->token_buffer + old_written + 1;\r
+      fend = cppReader_getPWritten (pfile) - 1;\r
+      if (fbeg[-1] == '<')\r
+       {\r
+         angle_brackets = 1;\r
+         /* If -I-, start with the first -I dir after the -I-.  */\r
+         if (CPPOPTIONS (pfile)->first_bracket_include != NULL)\r
+           search_start = CPPOPTIONS (pfile)->first_bracket_include;\r
+       }\r
+      /* If -I- was specified, don't search current dir, only spec'd ones.  */\r
+      else if (!CPPOPTIONS (pfile)->ignore_srcdir)\r
+       {\r
+         cppBuffer *fp = CPPBUFFER (pfile);\r
+         /* We have "filename".  Figure out directory this source\r
+            file is coming from and put it on the front of the list.  */\r
+\r
+         for ( ; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))\r
+           {\r
+             int n;\r
+             char *ep,*nam;\r
+\r
+             llassert (fp != NULL);\r
+\r
+             nam = NULL;\r
+\r
+             if (cstring_isDefined (fp->nominal_fname))\r
+               {\r
+                 nam = cstring_toCharsSafe (fp->nominal_fname);\r
+\r
+                 /* Found a named file.  Figure out dir of the file,\r
+                    and put it in front of the search list.  */\r
+                 dsp[0].next = search_start;\r
+                 search_start = dsp;\r
+\r
+#ifndef VMS\r
+                 ep = strrchr (nam, CONNECTCHAR);\r
+#else                          /* VMS */\r
+                 ep = strrchr (nam, ']');\r
+                 if (ep == NULL) ep = strrchr (nam, '>');\r
+                 if (ep == NULL) ep = strrchr (nam, ':');\r
+                 if (ep != NULL) ep++;\r
+#endif                         /* VMS */\r
+                 if (ep != NULL)\r
+                   {\r
+                     char save;\r
+\r
+                     n = ep - nam;\r
+                     save = nam[n];\r
+                     nam[n] = '\0';\r
+\r
+                     /*@-onlytrans@*/ /* This looks like a memory leak... */ \r
+                     dsp[0].fname = cstring_fromCharsNew (nam); /* evs 2000-07-20: was fromChars */\r
+                     /*@=onlytrans@*/\r
+                     nam[n] = save;\r
+\r
+                     if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len)\r
+                       pfile->max_include_len = n + INCLUDE_LEN_FUDGE;\r
+                   }\r
+                 else\r
+                   {\r
+                     dsp[0].fname = cstring_undefined; /* Current directory */\r
+                   }\r
+\r
+                 dsp[0].got_name_map = 0;\r
+                 break;\r
+               }\r
+           }\r
+       }\r
+      else\r
+       {\r
+         ;\r
+       }\r
+    }\r
+#ifdef VMS\r
+  else if (token == CPP_NAME)\r
+    {\r
+      /*\r
+       * Support '#include xyz' like VAX-C to allow for easy use of all the\r
+       * decwindow include files. It defaults to '#include <xyz.h>' (so the\r
+       * code from case '<' is repeated here) and generates a warning.\r
+       */\r
+      cppReader_warning (pfile,\r
+                  "VAX-C-style include specification found, use '#include <filename.h>' !");\r
+      angle_brackets = 1;\r
+      /* If -I-, start with the first -I dir after the -I-.  */\r
+      if (CPPOPTIONS (pfile)->first_bracket_include)\r
+       search_start = CPPOPTIONS (pfile)->first_bracket_include;\r
+      fbeg = pfile->token_buffer + old_written;\r
+      fend = cppReader_getPWritten (pfile);\r
+    }\r
+#endif\r
+  else\r
+    {\r
+      cppReader_error (pfile,\r
+                message ("Preprocessor command #%s expects \"FILENAME\" or <FILENAME>",\r
+                         keyword->name));\r
+\r
+      cppReader_setWritten (pfile, old_written);\r
+      cppReader_skipRestOfLine (pfile);\r
+      return 0;\r
+    }\r
+\r
+  *fend = 0;\r
+\r
+  token = get_directive_token (pfile);\r
+  if (token != CPP_VSPACE)\r
+    {\r
+      cppReader_errorLit (pfile,\r
+                   cstring_makeLiteralTemp ("Junk at end of #include"));\r
+\r
+      while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)\r
+       {\r
+         token = get_directive_token (pfile);\r
+       }\r
+    }\r
+\r
+  /*\r
+  ** For #include_next, skip in the search path\r
+  ** past the dir in which the containing file was found.\r
+  */\r
+\r
+  if (skip_dirs)\r
+    {\r
+      cppBuffer *fp = CPPBUFFER (pfile);\r
+\r
+      for (; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))\r
+       {\r
+         llassert (fp != NULL);\r
+\r
+         if (fp->fname != NULL)\r
+           {\r
+             /* fp->dir is null if the containing file was specified with\r
+                an absolute file name.  In that case, don't skip anything.  */\r
+             if (fp->dir == SELF_DIR_DUMMY)\r
+               {\r
+                 search_start = CPPOPTIONS (pfile)->include;\r
+               }\r
+             else if (fp->dir != NULL)\r
+               {\r
+                 search_start = fp->dir->next;\r
+               }\r
+             else\r
+               {\r
+                 ;\r
+               }\r
+\r
+             break;\r
+           }\r
+       }\r
+    }\r
+\r
+  cppReader_setWritten (pfile, old_written);\r
+\r
+  flen = fend - fbeg;\r
+\r
+  DPRINTF (("fbeg: %s", fbeg));\r
+\r
+  if (flen == 0)\r
+    {\r
+      cppReader_error (pfile,\r
+                message ("Empty file name in #%s", keyword->name));\r
+      return 0;\r
+    }\r
+\r
+  /*\r
+  ** Allocate this permanently, because it gets stored in the definitions\r
+  ** of macros.\r
+  */\r
+\r
+  fname = cstring_undefined;\r
+\r
+  /* + 2 above for slash and terminating null.  */\r
+  /* + 2 added for '.h' on VMS (to support '#include filename') */\r
+\r
+  /* If specified file name is absolute, just open it.  */\r
+\r
+  if (osd_isConnectChar (*fbeg)\r
+# if defined (WIN32) || defined (OS2)\r
+      || (*(fbeg + 1) == ':')\r
+# endif\r
+      )\r
+    {\r
+      fname = cstring_copyLength (fbeg, flen);\r
+      \r
+      if (redundant_include_p (pfile, fname))\r
+       {\r
+         cstring_free (fname);\r
+         return 0;\r
+       }\r
+      \r
+      f = open_include_file (pfile, fname, NULL);\r
+      \r
+      if (f == IMPORT_FOUND)\r
+       {\r
+         return 0;             /* Already included this file */\r
+       }\r
+    } \r
+  else \r
+    {\r
+      /* Search directory path, trying to open the file.\r
+        Copy each filename tried into FNAME.  */\r
+\r
+      for (searchptr = search_start; searchptr != NULL;\r
+          searchptr = searchptr->next)\r
+       {\r
+         if (!cstring_isEmpty (searchptr->fname))\r
+           {\r
+             /* The empty string in a search path is ignored.\r
+                This makes it possible to turn off entirely\r
+                a standard piece of the list.  */\r
+             if (cstring_isEmpty (searchptr->fname))\r
+               continue;\r
+             \r
+             fname = cstring_copy (searchptr->fname);\r
+             fname = cstring_appendChar (fname, CONNECTCHAR);\r
+             DPRINTF (("Here: %s", fname));\r
+           }\r
+         else\r
+           {\r
+             ;\r
+           }\r
+         \r
+         fname = cstring_concatLength (fname, fbeg, flen);\r
+\r
+         DPRINTF (("fname: %s", fname));\r
+         \r
+         /* Win32 directory fix from Kay Buschner. */\r
+#if defined (WIN32) || defined (OS2)\r
+         /* Fix all unixdir slashes to win dir slashes */\r
+         if (searchptr->fname && (searchptr->fname[0] != 0)) \r
+           {\r
+             cstring_replaceAll (fname, '/', '\\');\r
+           }\r
+#endif /* WIN32 */\r
+\r
+#ifdef VMS\r
+         /* Change this 1/2 Unix 1/2 VMS file specification into a\r
+            full VMS file specification */\r
+         if (searchptr->fname && (searchptr->fname[0] != 0)) {\r
+           /* Fix up the filename */\r
+           hack_vms_include_specification (fname);\r
+         } else {\r
+           /* This is a normal VMS filespec, so use it unchanged.  */\r
+           strncpy (fname, fbeg, flen);\r
+           fname[flen] = 0;\r
+           /* if it's '#include filename', add the missing .h */\r
+           if (strchr (fname,'.') == NULL) {\r
+             strcat (fname, ".h");\r
+           }\r
+         }\r
+#endif /* VMS */\r
+         /* ??? There are currently 3 separate mechanisms for avoiding processing\r
+            of redundant include files: #import, #pragma once, and\r
+            redundant_include_p.  It would be nice if they were unified.  */\r
+         \r
+         if (redundant_include_p (pfile, fname))\r
+           {\r
+             cstring_free (fname);\r
+             return 0;\r
+           }\r
+\r
+         DPRINTF (("Trying: %s", fname));\r
+\r
+         f = open_include_file (pfile, fname, searchptr);\r
+         \r
+         if (f == IMPORT_FOUND)\r
+           {\r
+             return 0;                 /* Already included this file */\r
+           }\r
+#ifdef EACCES\r
+         else if (f == IMPORT_NOT_FOUND && errno == EACCES)\r
+           {\r
+             cppReader_warning (pfile,\r
+                                message ("Header file %s exists, but is not readable", fname));\r
+           }\r
+#endif\r
+         \r
+         if (f >= 0)\r
+           {\r
+             break;\r
+           }\r
+       }\r
+    }\r
+  \r
+  if (f < 0)\r
+    {\r
+      /* A file that was not found.  */\r
+      fname = cstring_copyLength (fbeg, flen);\r
+\r
+      if (search_start != NULL)\r
+       {\r
+         cppReader_error (pfile,\r
+                          message ("Cannot find include file %s on search path: %x", \r
+                                   fname,\r
+                                   searchPath_unparse (search_start)));\r
+       }\r
+      else\r
+       {\r
+         cppReader_error (pfile,\r
+                          message ("No include path in which to find %s", fname));\r
+       }\r
+    }\r
+  else {\r
+    /*\r
+    ** Check to see if this include file is a once-only include file.\r
+    ** If so, give up.\r
+    */\r
+\r
+    struct file_name_list *ptr;\r
+\r
+    for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)\r
+      {\r
+       if (cstring_equal (ptr->fname, fname))\r
+         {\r
+           /* This file was included before.  */\r
+           break;\r
+         }\r
+      }\r
+\r
+    if (ptr == NULL)\r
+      {\r
+       /* This is the first time for this file.  */\r
+       /* Add it to list of files included.  */\r
+\r
+       ptr = (struct file_name_list *) dmalloc (sizeof (*ptr));\r
+       ptr->control_macro = NULL;\r
+       ptr->c_system_include_path = NULL;\r
+       ptr->next = pfile->all_include_files;\r
+       ptr->fname = fname;\r
+       ptr->got_name_map = NULL;\r
+\r
+       DPRINTF (("Including file: %s", fname));\r
+       pfile->all_include_files = ptr;\r
+       assertSet (pfile->all_include_files);\r
+      }\r
+\r
+    if (angle_brackets != 0)\r
+      {\r
+       pfile->system_include_depth++;\r
+      }\r
+\r
+    /* Actually process the file */\r
+    if (cppReader_pushBuffer (pfile, NULL, 0) == NULL)\r
+      {\r
+       cstring_free (fname);\r
+       return 0;\r
+      }\r
+\r
+    if (finclude (pfile, f, fname, is_system_include (pfile, fname),\r
+                 searchptr != dsp ? searchptr : SELF_DIR_DUMMY))\r
+      {\r
+       output_line_command (pfile, 0, enter_file);\r
+       pfile->only_seen_white = 2;\r
+      }\r
+\r
+    if (angle_brackets)\r
+      {\r
+       pfile->system_include_depth--;\r
+      }\r
+    /*@-branchstate@*/\r
+  } /*@=branchstate@*/ \r
+\r
+  return 0;\r
+}\r
+\r
+/* Return nonzero if there is no need to include file NAME\r
+   because it has already been included and it contains a conditional\r
+   to make a repeated include do nothing.  */\r
+\r
+static bool\r
+redundant_include_p (cppReader *pfile, cstring name)\r
+{\r
+  struct file_name_list *l = pfile->all_include_files;\r
+\r
+  for (; l != NULL; l = l->next)\r
+    {\r
+      if (cstring_equal (name, l->fname)\r
+         && (l->control_macro != NULL)\r
+         && (cppReader_lookup (l->control_macro, -1, -1) != NULL))\r
+       {\r
+         return TRUE;\r
+       }\r
+    }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/* Return nonzero if the given FILENAME is an absolute pathname which\r
+   designates a file within one of the known "system" include file\r
+   directories.  We assume here that if the given FILENAME looks like\r
+   it is the name of a file which resides either directly in a "system"\r
+   include file directory, or within any subdirectory thereof, then the\r
+   given file must be a "system" include file.  This function tells us\r
+   if we should suppress pedantic errors/warnings for the given FILENAME.\r
+\r
+   The value is 2 if the file is a C-language system header file\r
+   for which C++ should (on most systems) assume `extern "C"'.  */\r
+\r
+static bool\r
+is_system_include (cppReader *pfile, cstring filename)\r
+{\r
+  struct file_name_list *searchptr;\r
+\r
+  for (searchptr = CPPOPTIONS (pfile)->first_system_include;\r
+       searchptr != NULL;\r
+       searchptr = searchptr->next)\r
+    {\r
+      if (!cstring_isEmpty (searchptr->fname)) {\r
+       cstring sys_dir = searchptr->fname;\r
+       int length = cstring_length (sys_dir);\r
+\r
+       if (cstring_equalLen (sys_dir, filename, length)\r
+           && osd_isConnectChar (cstring_getChar (filename, length)))\r
+         {\r
+           if (searchptr->c_system_include_path)\r
+             return 2;\r
+           else\r
+             return 1;\r
+         }\r
+      }\r
+    }\r
+\r
+  return 0;\r
+}\r
+\r
+/* Convert a character string literal into a nul-terminated string.\r
+   The input string is [IN ... LIMIT).\r
+   The result is placed in RESULT.  RESULT can be the same as IN.\r
+   The value returned in the end of the string written to RESULT,\r
+   or NULL on error.  */\r
+\r
+static /*@null@*/ char *\r
+convert_string (cppReader *pfile, /*@returned@*/ char *result,\r
+               char *in, char *limit, int handle_escapes)\r
+{\r
+  char c;\r
+  c = *in++;\r
+\r
+  if (c != '\"')\r
+    {\r
+      return NULL;\r
+    }\r
+\r
+  while (in < limit)\r
+    {\r
+      c = *in++;\r
+\r
+      switch (c)\r
+       {\r
+       case '\0':\r
+         return NULL;\r
+       case '\"':\r
+         limit = in;\r
+         /*@switchbreak@*/ break;\r
+       case '\\':\r
+         if (handle_escapes)\r
+           {\r
+             char *bpc = (char *) in;\r
+             int i = (char) cppReader_parseEscape (pfile, &bpc);\r
+             in = (char *) bpc;\r
+             if (i >= 0)\r
+               *result++ = (char) c;\r
+             /*@switchbreak@*/ break;\r
+           }\r
+\r
+         /*@fallthrough@*/\r
+       default:\r
+         *result++ = c;\r
+       }\r
+    }\r
+\r
+  *result = 0;\r
+  return result;\r
+}\r
+\r
+/*\r
+ * interpret #line command.  Remembers previously seen fnames\r
+ * in its very own hash table.\r
+ */\r
+\r
+/*@constant int FNAME_HASHSIZE@*/\r
+#define FNAME_HASHSIZE 37\r
+\r
+static int\r
+do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)\r
+{\r
+  cppBuffer *ip = cppReader_getBuffer (pfile);\r
+  int new_lineno;\r
+  size_t old_written = cppReader_getWritten (pfile);\r
+  enum file_change_code file_change = same_file;\r
+  enum cpp_token token;\r
+\r
+  token = get_directive_token (pfile);\r
+\r
+  if (token != CPP_NUMBER\r
+      || !isdigit(pfile->token_buffer[old_written]))\r
+    {\r
+      cppReader_errorLit (pfile,\r
+                   cstring_makeLiteralTemp ("invalid format `#line' command"));\r
+\r
+      goto bad_line_directive;\r
+    }\r
+\r
+  /* The Newline at the end of this line remains to be processed.\r
+     To put the next line at the specified line number,\r
+     we must store a line number now that is one less.  */\r
+  new_lineno = atoi (pfile->token_buffer + old_written) - 1;\r
+  cppReader_setWritten (pfile, old_written);\r
+\r
+  /* NEW_LINENO is one less than the actual line number here.  */\r
+  if (cppReader_isPedantic (pfile) && new_lineno < 0)\r
+    cppReader_pedwarnLit (pfile,\r
+                   cstring_makeLiteralTemp ("line number out of range in `#line' command"));\r
+\r
+  token = get_directive_token (pfile);\r
+\r
+  if (token == CPP_STRING) {\r
+    char *fname = pfile->token_buffer + old_written;\r
+    char *end_name;\r
+    static hashNode fname_table[FNAME_HASHSIZE];\r
+    hashNode hp; \r
+    hashNode *hash_bucket;\r
+    char *p;\r
+    size_t num_start;\r
+    int fname_length;\r
+\r
+    /* Turn the file name, which is a character string literal,\r
+       into a null-terminated string.  Do this in place.  */\r
+    end_name = convert_string (pfile, fname, fname, cppReader_getPWritten (pfile), 1);\r
+    if (end_name == NULL)\r
+      {\r
+       cppReader_errorLit (pfile,\r
+                     cstring_makeLiteralTemp ("invalid format `#line' command"));\r
+       goto bad_line_directive;\r
+      }\r
+\r
+    fname_length = end_name - fname;\r
+    num_start = cppReader_getWritten (pfile);\r
+\r
+    token = get_directive_token (pfile);\r
+    if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {\r
+      p = pfile->token_buffer + num_start;\r
+      if (cppReader_isPedantic (pfile))\r
+       cppReader_pedwarnLit (pfile,\r
+                       cstring_makeLiteralTemp ("garbage at end of `#line' command"));\r
+\r
+      if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')\r
+       {\r
+         cppReader_errorLit (pfile,\r
+                       cstring_makeLiteralTemp ("invalid format `#line' command"));\r
+         goto bad_line_directive;\r
+       }\r
+      if (*p == '1')\r
+       file_change = enter_file;\r
+      else if (*p == 2)\r
+       file_change = leave_file;\r
+      else if (*p == 3)\r
+       ip->system_header_p = 1;\r
+      else /* if (*p == 4) */\r
+       ip->system_header_p = 2;\r
+\r
+      cppReader_setWritten (pfile, num_start);\r
+      token = get_directive_token (pfile);\r
+      p = pfile->token_buffer + num_start;\r
+      if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {\r
+       ip->system_header_p = *p == 3 ? 1 : 2;\r
+       token = get_directive_token (pfile);\r
+      }\r
+      if (token != CPP_VSPACE) {\r
+       cppReader_errorLit (pfile,\r
+                     cstring_makeLiteralTemp ("invalid format `#line' command"));\r
+\r
+       goto bad_line_directive;\r
+      }\r
+    }\r
+\r
+    hash_bucket =\r
+      &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];\r
+    for (hp = *hash_bucket; hp != NULL; hp = hp->next)\r
+      {\r
+       if (hp->length == fname_length &&\r
+           strncmp (hp->value.cpval, fname, size_fromInt (fname_length)) == 0) {\r
+         ip->nominal_fname = cstring_fromChars (hp->value.cpval);\r
+         break;\r
+       }\r
+      }\r
+\r
+    if (hp == 0) {\r
+      /* Didn't find it; cons up a new one.  */\r
+      hp = (hashNode) dmalloc (sizeof (*hp));\r
+\r
+      hp->prev = NULL;\r
+      hp->bucket_hdr = NULL;\r
+      hp->type = T_NONE;\r
+      hp->name = cstring_undefined;\r
+      hp->next = *hash_bucket;\r
+\r
+      *hash_bucket = hp;\r
+\r
+      hp->length = fname_length;\r
+      hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));\r
+      memcpy (hp->value.cpval, fname, size_fromInt (fname_length));\r
+      hp->value.cpval[fname_length] = '\0';\r
+      ip->nominal_fname = cstring_fromChars (hp->value.cpval);\r
+    }\r
+  }\r
+  else if (token != CPP_VSPACE && token != CPP_EOF)\r
+    {\r
+      cppReader_errorLit (pfile,\r
+                   cstring_makeLiteralTemp ("invalid format `#line' command"));\r
+      goto bad_line_directive;\r
+    }\r
+  else\r
+    {\r
+      ;\r
+    }\r
+\r
+  ip->lineno = new_lineno;\r
+bad_line_directive:\r
+  cppReader_skipRestOfLine (pfile);\r
+  cppReader_setWritten (pfile, old_written);\r
+  output_line_command (pfile, 0, file_change);\r
+  return 0;\r
+}\r
+\r
+/*\r
+ * remove the definition of a symbol from the symbol table.\r
+ * according to un*x /lib/cpp, it is not an error to undef\r
+ * something that has no definitions, so it isn't one here either.\r
+ */\r
+\r
+static int\r
+do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)\r
+{\r
+\r
+  int sym_length;\r
+  hashNode hp;\r
+  char *orig_buf = buf;\r
+\r
+  SKIP_WHITE_SPACE (buf);\r
+\r
+  sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));\r
+\r
+  while ((hp = cppReader_lookup (buf, sym_length, -1)) != NULL)\r
+    {\r
+      /* If we are generating additional info for debugging (with -g) we\r
+        need to pass through all effective #undef commands.  */\r
+      if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))\r
+       {\r
+         pass_thru_directive (orig_buf, limit, pfile, keyword);\r
+       }\r
+\r
+      if (hp->type != T_MACRO)\r
+       {\r
+         cppReader_warning (pfile,\r
+                      message ("Undefining preprocessor builtin: %s",\r
+                               hp->name));\r
+       }\r
+\r
+      cppReader_deleteMacro (hp);\r
+    }\r
+\r
+  if (cppReader_isPedantic (pfile)) {\r
+    buf += sym_length;\r
+    SKIP_WHITE_SPACE (buf);\r
+    if (buf != limit)\r
+      {\r
+       cppReader_pedwarnLit (pfile,\r
+                       cstring_makeLiteralTemp ("garbage after `#undef' directive"));\r
+      }\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+\r
+/*\r
+ * Report an error detected by the program we are processing.\r
+ * Use the text of the line in the error message.\r
+ * (We use error because it prints the filename & line#.)\r
+ */\r
+\r
+static int\r
+do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,\r
+         char *buf, char *limit)\r
+{\r
+  int length = limit - buf;\r
+  cstring copy = cstring_copyLength (buf, length);\r
+  cstring adv = cstring_advanceWhiteSpace (copy);\r
+\r
+  cppReader_error (pfile, message ("#error %s", adv));\r
+  cstring_free (copy);\r
+  return 0;\r
+}\r
+\r
+/*\r
+ * Report a warning detected by the program we are processing.\r
+ * Use the text of the line in the warning message, then continue.\r
+ * (We use error because it prints the filename & line#.)\r
+ */\r
+\r
+static int\r
+do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,\r
+           char *buf, char *limit)\r
+{\r
+  int length = limit - buf;\r
+  cstring copy = cstring_copyLength (buf, length);\r
+  cstring adv = cstring_advanceWhiteSpace (copy);\r
+  cppReader_warning (pfile, message ("#warning %s", adv));\r
+  cstring_free (copy);\r
+  return 0;\r
+}\r
+\r
+\r
+/* #ident has already been copied to the output file, so just ignore it.  */\r
+\r
+static int\r
+do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword,\r
+         /*@unused@*/ char *buf, /*@unused@*/ char *limit)\r
+{\r
+  /* Allow #ident in system headers, since that's not user's fault.  */\r
+  if (cppReader_isPedantic (pfile) && !cppReader_getBuffer (pfile)->system_header_p)\r
+    cppReader_pedwarnLit (pfile,\r
+                   cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));\r
+\r
+  /* Leave rest of line to be read by later calls to cppGetToken.  */\r
+\r
+  return 0;\r
+}\r
+\r
+/* #pragma and its argument line have already been copied to the output file.\r
+   Just check for some recognized pragmas that need validation here.  */\r
+\r
+static int\r
+do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,\r
+          /*@unused@*/ char *buf, /*@unused@*/ char *limit)\r
+{\r
+  while (*buf == ' ' || *buf == '\t')\r
+    {\r
+      buf++;\r
+    }\r
+\r
+  if (!strncmp (buf, "implementation", 14)) {\r
+    /* Be quiet about `#pragma implementation' for a file only if it hasn't\r
+       been included yet.  */\r
+    struct file_name_list *ptr;\r
+    char *p = buf + 14, *fname, *inc_fname;\r
+    int fname_len;\r
+    SKIP_WHITE_SPACE (p);\r
+    if (*p == '\n' || *p != '\"')\r
+      return 0;\r
+\r
+    fname = p + 1;\r
+    p = (char *) strchr (fname, '\"');\r
+    fname_len = p != NULL ? p - fname : mstring_length (fname);\r
+\r
+    for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)\r
+      {\r
+       inc_fname = (char *) strrchr (cstring_toCharsSafe (ptr->fname), CONNECTCHAR);\r
+       inc_fname = (inc_fname != NULL)\r
+         ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);\r
+\r
+       if ((inc_fname != NULL)\r
+           && (strncmp (inc_fname, fname, size_fromInt (fname_len)) == 0))\r
+         {\r
+           cpp_setLocation (pfile);\r
+\r
+           ppllerror (message ("`#pragma implementation' for `%s' appears "\r
+                               "after file is included",\r
+                               cstring_fromChars (fname)));\r
+         }\r
+      }\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+/*\r
+ * handle #if command by\r
+ *   1) inserting special `defined' keyword into the hash table\r
+ *     that gets turned into 0 or 1 by special_symbol (thus,\r
+ *     if the luser has a symbol called `defined' already, it won't\r
+ *      work inside the #if command)\r
+ *   2) rescan the input into a temporary output buffer\r
+ *   3) pass the output buffer to the yacc parser and collect a value\r
+ *   4) clean up the mess left from steps 1 and 2.\r
+ *   5) call conditional_skip to skip til the next #endif (etc.),\r
+ *      or not, depending on the value from step 3.\r
+ */\r
+\r
+static int\r
+do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,\r
+       char *buf, char *limit)\r
+{\r
+  HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);\r
+  conditional_skip (pfile, value == 0, T_IF, NULL);\r
+  return 0;\r
+}\r
+\r
+/*\r
+ * handle a #elif directive by not changing  if_stack  either.\r
+ * see the comment above do_else.\r
+ */\r
+\r
+static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,\r
+                   char *buf, char *limit)\r
+{\r
+  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)\r
+    {\r
+      cppReader_errorLit (pfile,\r
+                   cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));\r
+      return 0;\r
+    }\r
+  else\r
+    {\r
+      llassert (pfile->if_stack != NULL);\r
+\r
+      if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)\r
+       {\r
+         cppReader_errorLit (pfile,\r
+                       cstring_makeLiteralTemp ("`#elif' after `#else'"));\r
+\r
+         if (pfile->if_stack->fname != NULL\r
+             && cppReader_getBuffer (pfile)->fname != NULL\r
+             && !cstring_equal (pfile->if_stack->fname,\r
+                                cppReader_getBuffer (pfile)->nominal_fname))\r
+           fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));\r
+         fprintf (stderr, ")\n");\r
+       }\r
+      pfile->if_stack->type = T_ELIF;\r
+    }\r
+\r
+  if (pfile->if_stack->if_succeeded)\r
+    {\r
+      skip_if_group (pfile, 0);\r
+    }\r
+  else\r
+    {\r
+      HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);\r
+      if (value == 0)\r
+       skip_if_group (pfile, 0);\r
+      else\r
+       {\r
+         ++pfile->if_stack->if_succeeded;      /* continue processing input */\r
+         output_line_command (pfile, 1, same_file);\r
+       }\r
+    }\r
+\r
+  return 0;\r
+}\r
+\r
+/*\r
+ * evaluate a #if expression in BUF, of length LENGTH,\r
+ * then parse the result as a C expression and return the value as an int.\r
+ */\r
+\r
+static HOST_WIDE_INT\r
+eval_if_expression (cppReader *pfile,\r
+                   /*@unused@*/ char *buf,\r
+                   /*@unused@*/ int length)\r
+{\r
+  hashNode save_defined;\r
+  HOST_WIDE_INT value;\r
+  size_t old_written = cppReader_getWritten (pfile);\r
+\r
+  save_defined = cppReader_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);\r
+  pfile->pcp_inside_if = 1;\r
+\r
+  value = cppReader_parseExpression (pfile);\r
+  pfile->pcp_inside_if = 0;\r
+\r
+  /* Clean up special symbol */\r
+  cppReader_deleteMacro (save_defined);\r
+\r
+  cppReader_setWritten (pfile, old_written); /* Pop */\r
+\r
+  return value;\r
+}\r
+\r
+/*\r
+ * routine to handle ifdef/ifndef.  Try to look up the symbol,\r
+ * then do or don't skip to the #endif/#else/#elif depending\r
+ * on what directive is actually being processed.\r
+ */\r
+\r
+static int\r
+do_xifdef (cppReader *pfile, struct directive *keyword,\r
+          /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)\r
+{\r
+  int skip;\r
+  cppBuffer *ip = cppReader_getBuffer (pfile);\r
+  char *ident;\r
+  int ident_length;\r
+  enum cpp_token token;\r
+  int start_of_file = 0;\r
+  char *control_macro = 0;\r
+  size_t old_written = cppReader_getWritten (pfile);\r
+\r
+  DPRINTF (("do xifdef: %d",\r
+           keyword->type == T_IFNDEF));\r
+\r
+  /* Detect a #ifndef at start of file (not counting comments).  */\r
+  if (cstring_isDefined (ip->fname) && keyword->type == T_IFNDEF)\r
+    {\r
+      start_of_file = pfile->only_seen_white == 2;\r
+    }\r
+\r
+  pfile->no_macro_expand++;\r
+  token = get_directive_token (pfile);\r
+  pfile->no_macro_expand--;\r
+\r
+  ident = pfile->token_buffer + old_written;\r
+  ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);\r
+  cppReader_setWritten (pfile, old_written); /* Pop */\r
+\r
+  if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)\r
+    {\r
+      skip = (keyword->type == T_IFDEF);\r
+      if (! cppReader_isTraditional (pfile))\r
+       {\r
+         cppReader_pedwarn (pfile,\r
+                      message ("`#%s' with no argument", keyword->name));\r
+       }\r
+    }\r
+  else if (token == CPP_NAME)\r
+    {\r
+      hashNode hp = cppReader_lookup (ident, ident_length, -1);\r
+      skip = (keyword->type == T_IFDEF) \r
+       ? (hp == NULL) : (hp != NULL);\r
+\r
+      DPRINTF (("hp null: %d / %d / %d",\r
+               (hp == NULL),\r
+               (keyword->type == T_IFNDEF),\r
+               skip));\r
+               \r
+      if (start_of_file && !skip)\r
+       {\r
+         DPRINTF (("Not skipping!"));\r
+         control_macro = (char *) dmalloc (size_fromInt (ident_length + 1));\r
+         memcpy (control_macro, ident, size_fromInt (ident_length + 1));\r
+       }\r
+    }\r
+  else\r
+    {\r
+      skip = (keyword->type == T_IFDEF);\r
+      if (! cppReader_isTraditional (pfile))\r
+       {\r
+         cppReader_error (pfile,\r
+                    message ("`#%s' with invalid argument", keyword->name));\r
+       }\r
+    }\r
+\r
+  if (!cppReader_isTraditional (pfile))\r
+    {\r
+      int c;\r
+      cppSkipHspace (pfile);\r
+      c = cppReader_peekC (pfile);\r
+      if (c != EOF && c != '\n')\r
+       {\r
+         cppReader_pedwarn (pfile,\r
+                            message ("garbage at end of `#%s' argument", keyword->name));\r
+       }\r
+    }\r
+\r
+  cppReader_skipRestOfLine (pfile);\r
+\r
+  DPRINTF (("Conditional skip: %d", skip));\r
+  conditional_skip (pfile, skip, T_IF, control_macro);\r
+  return 0;\r
+}\r
+\r
+/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.\r
+   If this is a #ifndef starting at the beginning of a file,\r
+   CONTROL_MACRO is the macro name tested by the #ifndef.\r
+   Otherwise, CONTROL_MACRO is 0.  */\r
+\r
+static void\r
+conditional_skip (cppReader *pfile, int skip,\r
+                 enum node_type type,\r
+                 /*@dependent@*/ char *control_macro)\r
+{\r
+  cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));\r
+\r
+  temp->fname = cppReader_getBuffer (pfile)->nominal_fname;\r
+  temp->next = pfile->if_stack;\r
+  temp->control_macro = control_macro;\r
+  temp->lineno = 0;\r
+  temp->if_succeeded = 0;\r
+\r
+  pfile->if_stack = temp;\r
+  pfile->if_stack->type = type;\r
+\r
+  if (skip != 0)\r
+    {\r
+      skip_if_group (pfile, 0);\r
+      return;\r
+    }\r
+  else\r
+    {\r
+      ++pfile->if_stack->if_succeeded;\r
+      output_line_command (pfile, 1, same_file);\r
+    }\r
+}\r
+\r
+/*\r
+ * skip to #endif, #else, or #elif.  adjust line numbers, etc.\r
+ * leaves input ptr at the sharp sign found.\r
+ * If ANY is nonzero, return at next directive of any sort.\r
+ */\r
+\r
+static void\r
+skip_if_group (cppReader *pfile, int any)\r
+{\r
+  int c;\r
+  struct directive *kt;\r
+  cppIfStackFrame *save_if_stack = pfile->if_stack; /* don't pop past here */\r
+  register int ident_length;\r
+  char *ident;\r
+  struct parse_marker line_start_mark;\r
+\r
+  parseSetMark (&line_start_mark, pfile);\r
+\r
+  if (CPPOPTIONS (pfile)->output_conditionals) {\r
+    static char failed[] = "#failed\n";\r
+    cppReader_puts (pfile, failed, sizeof(failed)-1);\r
+    pfile->lineno++;\r
+    output_line_command (pfile, 1, same_file);\r
+  }\r
+\r
+beg_of_line:\r
+  if (CPPOPTIONS (pfile)->output_conditionals)\r
+    {\r
+      cppBuffer *pbuf = cppReader_getBuffer (pfile);\r
+      char *start_line;\r
+\r
+      llassert (pbuf->buf != NULL);\r
+\r
+      start_line = pbuf->buf + line_start_mark.position;\r
+      cppReader_puts (pfile, start_line, size_fromInt (pbuf->cur - start_line));\r
+    }\r
+\r
+  parseMoveMark (&line_start_mark, pfile);\r
+\r
+  if (!cppReader_isTraditional (pfile))\r
+    {\r
+      cppSkipHspace (pfile);\r
+    }\r
+\r
+  c  = cppReader_getC (pfile);\r
+  if (c == '#')\r
+    {\r
+      size_t old_written = cppReader_getWritten (pfile);\r
+      cppSkipHspace (pfile);\r
+\r
+      parse_name (pfile, cppReader_getC (pfile));\r
+      ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);\r
+      ident = pfile->token_buffer + old_written;\r
+      pfile->limit = ident;\r
+\r
+      for (kt = directive_table; kt->length >= 0; kt++)\r
+       {\r
+         cppIfStackFrame *temp;\r
+         if (ident_length == kt->length\r
+             && cstring_equalPrefix (kt->name, cstring_fromChars (ident)))\r
+           {\r
+             /* If we are asked to return on next directive, do so now.  */\r
+             if (any)\r
+               {\r
+                 goto done;\r
+               }\r
+\r
+             switch (kt->type)\r
+               {\r
+               case T_IF:\r
+               case T_IFDEF:\r
+               case T_IFNDEF:\r
+                 temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));\r
+                 temp->next = pfile->if_stack;\r
+                 temp->fname = cppReader_getBuffer (pfile)->nominal_fname;\r
+                 temp->type = kt->type;\r
+                 temp->lineno = 0;\r
+                 temp->if_succeeded = 0;\r
+                 temp->control_macro = NULL;\r
+\r
+                 pfile->if_stack = temp;\r
+                 /*@switchbreak@*/ break;\r
+               case T_ELSE:\r
+               case T_ENDIF:\r
+                 if (cppReader_isPedantic (pfile) && pfile->if_stack != save_if_stack)\r
+                   validate_else (pfile,\r
+                                  cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));\r
+                 /*@fallthrough@*/\r
+               case T_ELIF:\r
+                 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)\r
+                   {\r
+                     cppReader_error (pfile,\r
+                                message ("Preprocessor command #%s is not within a conditional", kt->name));\r
+                     /*@switchbreak@*/ break;\r
+                   }\r
+                 else if (pfile->if_stack == save_if_stack)\r
+                   {\r
+                     goto done;                /* found what we came for */\r
+                   }\r
+                 else\r
+                   {\r
+                     ;\r
+                   }\r
+\r
+                 if (kt->type != T_ENDIF)\r
+                   {\r
+                     llassert (pfile->if_stack != NULL);\r
+\r
+                     if (pfile->if_stack->type == T_ELSE)\r
+                       {\r
+                         cppReader_errorLit (pfile,\r
+                                       cstring_makeLiteralTemp ("`#else' or `#elif' after `#else'"));\r
+                       }\r
+\r
+                     pfile->if_stack->type = kt->type;\r
+                     /*@switchbreak@*/ break;\r
+                   }\r
+\r
+                 temp = pfile->if_stack;\r
+                 llassert (temp != NULL);\r
+                 pfile->if_stack = temp->next;\r
+                 sfree (temp);\r
+                 /*@switchbreak@*/ break;\r
+               default: ;\r
+                 /*@-branchstate@*/ \r
+               }\r
+             /*@=branchstate@*/\r
+             break;\r
+           }\r
+         \r
+         /* Don't let erroneous code go by.  */\r
+         \r
+         if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm\r
+             && cppReader_isPedantic (pfile))\r
+           {\r
+             cppReader_pedwarnLit (pfile,\r
+                                   cstring_makeLiteralTemp ("Invalid preprocessor directive name"));\r
+           }\r
+       }\r
+\r
+      c = cppReader_getC (pfile);\r
+    }\r
+  /* We're in the middle of a line.  Skip the rest of it.  */\r
+  for (;;) {\r
+    size_t old;\r
+\r
+    switch (c)\r
+      {\r
+      case EOF:\r
+       goto done;\r
+      case '/':                        /* possible comment */\r
+       c = skip_comment (pfile, NULL);\r
+       if (c == EOF)\r
+         goto done;\r
+       /*@switchbreak@*/ break;\r
+      case '\"':\r
+      case '\'':\r
+       cppReader_forward (pfile, -1);\r
+       old = cppReader_getWritten (pfile);\r
+       (void) cppGetToken (pfile);\r
+       cppReader_setWritten (pfile, old);\r
+       /*@switchbreak@*/ break;\r
+      case '\\':\r
+       /* Char after backslash loses its special meaning.  */\r
+       if (cppReader_peekC (pfile) == '\n')\r
+         {\r
+           cppReader_forward (pfile, 1);\r
+         }\r
+\r
+       /*@switchbreak@*/ break;\r
+      case '\n':\r
+       goto beg_of_line;\r
+      }\r
+    c = cppReader_getC (pfile);\r
+  }\r
+done:\r
+  if (CPPOPTIONS (pfile)->output_conditionals) {\r
+    static char end_failed[] = "#endfailed\n";\r
+    cppReader_puts (pfile, end_failed, sizeof(end_failed)-1);\r
+    pfile->lineno++;\r
+  }\r
+  pfile->only_seen_white = 1;\r
+\r
+  parseGotoMark (&line_start_mark, pfile);\r
+  parseClearMark (&line_start_mark);\r
+}\r
+\r
+/*\r
+ * handle a #else directive.  Do this by just continuing processing\r
+ * without changing  if_stack ;  this is so that the error message\r
+ * for missing #endif's etc. will point to the original #if.  It\r
+ * is possible that something different would be better.\r
+ */\r
+\r
+static int\r
+do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,\r
+       /*@unused@*/ char *buf, /*@unused@*/ char *limit)\r
+{\r
+  if (cppReader_isPedantic (pfile))\r
+    {\r
+      validate_else (pfile, cstring_makeLiteralTemp ("#else"));\r
+    }\r
+\r
+  cppReader_skipRestOfLine (pfile);\r
+\r
+  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) {\r
+    cppReader_errorLit (pfile,\r
+                 cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));\r
+    return 0;\r
+  } else {\r
+    /* #ifndef can't have its special treatment for containing the whole file\r
+       if it has a #else clause.  */\r
+\r
+    llassert (pfile->if_stack != NULL);\r
+\r
+    pfile->if_stack->control_macro = 0;\r
+\r
+    if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)\r
+      {\r
+       cpp_setLocation (pfile);\r
+       genppllerrorhint (FLG_PREPROC,\r
+                         message ("Pre-processor directive #else after #else"),\r
+                         message ("%q: Location of match",\r
+                                  fileloc_unparseRaw (pfile->if_stack->fname,\r
+                                                      pfile->if_stack->lineno)));\r
+      }\r
+\r
+    pfile->if_stack->type = T_ELSE;\r
+  }\r
+\r
+  if (pfile->if_stack->if_succeeded)\r
+    skip_if_group (pfile, 0);\r
+  else {\r
+    ++pfile->if_stack->if_succeeded;   /* continue processing input */\r
+    output_line_command (pfile, 1, same_file);\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+/*\r
+ * unstack after #endif command\r
+ */\r
+\r
+static int\r
+do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,\r
+         /*@unused@*/ char *buf, /*@unused@*/ char *limit)\r
+{\r
+  if (cppReader_isPedantic (pfile))\r
+    {\r
+      validate_else (pfile, cstring_makeLiteralTemp ("#endif"));\r
+    }\r
+\r
+  cppReader_skipRestOfLine (pfile);\r
+\r
+  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)\r
+    {\r
+      cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));\r
+    }\r
+  else\r
+    {\r
+      cppIfStackFrame *temp = pfile->if_stack;\r
+\r
+      llassert (temp != NULL);\r
+\r
+      pfile->if_stack = temp->next;\r
+      if (temp->control_macro != 0)\r
+       {\r
+         /* This #endif matched a #ifndef at the start of the file.\r
+            See if it is at the end of the file.  */\r
+         struct parse_marker start_mark;\r
+         int c;\r
+\r
+         parseSetMark (&start_mark, pfile);\r
+\r
+         for (;;)\r
+           {\r
+             cppSkipHspace (pfile);\r
+             c = cppReader_getC (pfile);\r
+\r
+             if (c != '\n')\r
+               break;\r
+           }\r
+\r
+         parseGotoMark (&start_mark, pfile);\r
+         parseClearMark (&start_mark);\r
+\r
+         if (c == EOF)\r
+           {\r
+             /* If we get here, this #endif ends a #ifndef\r
+                that contains all of the file (aside from whitespace).\r
+                Arrange not to include the file again\r
+                if the macro that was tested is defined.\r
+\r
+                Do not do this for the top-level file in a -include or any\r
+                file in a -imacros.  */\r
+             struct file_name_list *ifile = pfile->all_include_files;\r
+\r
+             for ( ; ifile != NULL; ifile = ifile->next)\r
+               {\r
+                 if (cstring_equal (ifile->fname, cppReader_getBuffer (pfile)->fname))\r
+                   {\r
+                     ifile->control_macro = temp->control_macro;\r
+                     break;\r
+                   }\r
+               }\r
+           }\r
+       }\r
+\r
+      sfree (temp);\r
+      output_line_command (pfile, 1, same_file);\r
+    }\r
+  return 0;\r
+}\r
+\r
+/* When an #else or #endif is found while skipping failed conditional,\r
+   if -pedantic was specified, this is called to warn about text after\r
+   the command name.  P points to the first char after the command name.  */\r
+\r
+static void\r
+validate_else (cppReader *pfile, cstring directive)\r
+{\r
+  int c;\r
+  cppSkipHspace (pfile);\r
+  c = cppReader_peekC (pfile);\r
+  if (c != EOF && c != '\n')\r
+    {\r
+      cppReader_pedwarn (pfile,\r
+                  message ("text following `%s' violates ANSI standard", directive));\r
+    }\r
+}\r
+\r
+/*\r
+** Get the next token, and add it to the text in pfile->token_buffer.\r
+** Return the kind of token we got.\r
+*/\r
+\r
+enum cpp_token\r
+cppGetToken (cppReader *pfile)\r
+{\r
+  int c, c2, c3;\r
+  size_t old_written = 0;\r
+  int start_line, start_column;\r
+  enum cpp_token token;\r
+  struct cppOptions *opts = CPPOPTIONS (pfile);\r
+  cppReader_getBuffer (pfile)->prev = cppReader_getBuffer (pfile)->cur;\r
+\r
+get_next:\r
+  c = cppReader_getC (pfile);\r
+\r
+  if (c == EOF)\r
+    {\r
+    handle_eof:\r
+      if (cppReader_getBuffer (pfile)->seen_eof)\r
+       {\r
+         cppBuffer *buf = cppReader_popBuffer (pfile);\r
+\r
+         if (buf != cppReader_nullBuffer (pfile))\r
+           {\r
+             goto get_next;\r
+           }\r
+         else\r
+           {\r
+             return CPP_EOF;\r
+           }\r
+       }\r
+      else\r
+       {\r
+         cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));\r
+         cppReader_getBuffer (pfile)->seen_eof = 1;\r
+\r
+         if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname)\r
+             && next_buf != cppReader_nullBuffer (pfile))\r
+           {\r
+             /* We're about to return from an #include file.\r
+                Emit #line information now (as part of the CPP_POP) result.\r
+                But the #line refers to the file we will pop to.  */\r
+             cppBuffer *cur_buffer = CPPBUFFER (pfile);\r
+             CPPBUFFER (pfile) = next_buf;\r
+             pfile->input_stack_listing_current = 0;\r
+             output_line_command (pfile, 0, leave_file);\r
+             CPPBUFFER (pfile) = cur_buffer;\r
+           }\r
+         return CPP_POP;\r
+       }\r
+    }\r
+  else\r
+    {\r
+      long newlines;\r
+      struct parse_marker start_mark;\r
+\r
+      switch (c)\r
+       {\r
+       case '/':\r
+         if (cppReader_peekC (pfile) == '=')\r
+           {\r
+             goto op2;\r
+           }\r
+\r
+         if (opts->put_out_comments)\r
+           {\r
+             parseSetMark (&start_mark, pfile);\r
+           }\r
+\r
+         newlines = 0;\r
+         cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),\r
+                                  &start_line, &start_column);\r
+         c = skip_comment (pfile, &newlines);\r
+\r
+         if (opts->put_out_comments && (c == '/' || c == EOF))\r
+           {\r
+             assertSet (&start_mark);\r
+             parseClearMark (&start_mark);\r
+           }\r
+\r
+         if (c == '/')\r
+           goto randomchar;\r
+         if (c == EOF)\r
+           {\r
+             cppReader_errorWithLine (pfile, start_line, start_column,\r
+                                      cstring_makeLiteral ("Unterminated comment"));\r
+             goto handle_eof;\r
+           }\r
+         c = '/';  /* Initial letter of comment.  */\r
+       return_comment:\r
+         /* Comments are equivalent to spaces.\r
+            For -traditional, a comment is equivalent to nothing.  */\r
+\r
+         if (opts->put_out_comments)\r
+           {\r
+             enum cpp_token res;\r
+\r
+             assertSet (&start_mark);\r
+             res = cpp_handleComment (pfile, &start_mark);\r
+             pfile->lineno += newlines;\r
+             return res;\r
+           }\r
+         else if (cppReader_isTraditional (pfile))\r
+           {\r
+             return CPP_COMMENT;\r
+           }\r
+         else\r
+           {\r
+             cppReader_reserve(pfile, 1);\r
+             cppReader_putCharQ (pfile, ' ');\r
+             return CPP_HSPACE;\r
+           }\r
+\r
+       case '#':\r
+         if (!pfile->only_seen_white)\r
+           {\r
+             goto randomchar;\r
+           }\r
+\r
+         if (cppReader_handleDirective (pfile))\r
+           {\r
+             return CPP_DIRECTIVE;\r
+           }\r
+\r
+         pfile->only_seen_white = 0;\r
+         return CPP_OTHER;\r
+\r
+       case '\"':\r
+       case '\'':\r
+         /* A single quoted string is treated like a double -- some\r
+            programs (e.g., troff) are perverse this way */\r
+         cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),\r
+                                  &start_line, &start_column);\r
+         old_written = cppReader_getWritten (pfile);\r
+       string:\r
+         cppReader_putChar (pfile, c);\r
+         while (TRUE)\r
+           {\r
+             int cc = cppReader_getC (pfile);\r
+             if (cc == EOF)\r
+               {\r
+                 if (cppBuffer_isMacro (CPPBUFFER (pfile)))\r
+                   {\r
+                     /* try harder: this string crosses a macro expansion\r
+                        boundary.  This can happen naturally if -traditional.\r
+                        Otherwise, only -D can make a macro with an unmatched\r
+                        quote.  */\r
+                     cppBuffer *next_buf\r
+                       = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));\r
+                     (*cppReader_getBuffer (pfile)->cleanup)\r
+                       (cppReader_getBuffer (pfile), pfile);\r
+                     CPPBUFFER (pfile) = next_buf;\r
+                     continue;\r
+                   }\r
+                 if (!cppReader_isTraditional (pfile))\r
+                   {\r
+                     cpp_setLocation (pfile);\r
+\r
+                     setLine (long_toInt (start_line));\r
+                     setColumn (long_toInt (start_column));\r
+\r
+                     if (pfile->multiline_string_line != long_toInt (start_line)\r
+                         && pfile->multiline_string_line != 0)\r
+                       {\r
+                         genppllerrorhint\r
+                           (FLG_PREPROC,\r
+                            message ("Unterminated string or character constant"),\r
+                            message ("%q: Possible real start of unterminated constant",\r
+                                     fileloc_unparseRaw \r
+                                     (fileloc_filename (g_currentloc),\r
+                                      pfile->multiline_string_line)));\r
+                         pfile->multiline_string_line = 0;\r
+                       }\r
+                     else\r
+                       {\r
+                         genppllerror\r
+                           (FLG_PREPROC,\r
+                            message ("Unterminated string or character constant"));\r
+                       }\r
+                   }\r
+                 /*@loopbreak@*/ break;\r
+               }\r
+             cppReader_putChar (pfile, cc);\r
+             switch (cc)\r
+               {\r
+               case '\n':\r
+                 /* Traditionally, end of line ends a string constant with\r
+                    no error.  So exit the loop and record the new line.  */\r
+                 if (cppReader_isTraditional (pfile))\r
+                   goto while2end;\r
+                 if (c == '\'')\r
+                   {\r
+                     goto while2end;\r
+                   }\r
+                 if (cppReader_isPedantic (pfile)\r
+                     && pfile->multiline_string_line == 0)\r
+                   {\r
+                     cppReader_pedwarnWithLine\r
+                       (pfile, long_toInt (start_line),\r
+                        long_toInt (start_column),\r
+                        cstring_makeLiteral ("String constant runs past end of line"));\r
+                   }\r
+                 if (pfile->multiline_string_line == 0)\r
+                   {\r
+                     pfile->multiline_string_line = start_line;\r
+                   }\r
+\r
+                 /*@switchbreak@*/ break;\r
+\r
+               case '\\':\r
+                 cc = cppReader_getC (pfile);\r
+                 if (cc == '\n')\r
+                   {\r
+                     /* Backslash newline is replaced by nothing at all.  */\r
+                     cppReader_adjustWritten (pfile, -1);\r
+                     pfile->lineno++;\r
+                   }\r
+                 else\r
+                   {\r
+                     /* ANSI stupidly requires that in \\ the second \\r
+                        is *not* prevented from combining with a newline.  */\r
+                     NEWLINE_FIX1(cc);\r
+                     if (cc != EOF)\r
+                       cppReader_putChar (pfile, cc);\r
+                   }\r
+                 /*@switchbreak@*/ break;\r
+\r
+               case '\"':\r
+               case '\'':\r
+                 if (cc == c)\r
+                   goto while2end;\r
+                 /*@switchbreak@*/ break;\r
+               }\r
+           }\r
+       while2end:\r
+         pfile->lineno += count_newlines (pfile->token_buffer + old_written,\r
+                                          cppReader_getPWritten (pfile));\r
+         pfile->only_seen_white = 0;\r
+         return c == '\'' ? CPP_CHAR : CPP_STRING;\r
+\r
+       case '$':\r
+         if (!opts->dollars_in_ident)\r
+           goto randomchar;\r
+         goto letter;\r
+\r
+       case ':':\r
+         if (opts->cplusplus && cppReader_peekC (pfile) == ':')\r
+           goto op2;\r
+         goto randomchar;\r
+\r
+       case '&':\r
+       case '+':\r
+       case '|':\r
+         NEWLINE_FIX;\r
+         c2 = cppReader_peekC (pfile);\r
+         if (c2 == c || c2 == '=')\r
+           goto op2;\r
+         goto randomchar;\r
+\r
+       case '*':\r
+       case '!':\r
+       case '%':\r
+       case '=':\r
+       case '^':\r
+         NEWLINE_FIX;\r
+         if (cppReader_peekC (pfile) == '=')\r
+           goto op2;\r
+         goto randomchar;\r
+\r
+       case '-':\r
+         NEWLINE_FIX;\r
+         c2 = cppReader_peekC (pfile);\r
+         if (c2 == '-' && opts->chill)\r
+           {\r
+             /* Chill style comment */\r
+             if (opts->put_out_comments)\r
+               {\r
+                 parseSetMark (&start_mark, pfile);\r
+               }\r
+\r
+             cppReader_forward (pfile, 1);  /* Skip second '-'.  */\r
+\r
+             for (;;)\r
+               {\r
+                 c = cppReader_getC (pfile);\r
+                 if (c == EOF)\r
+                   /*@loopbreak@*/ break;\r
+                 if (c == '\n')\r
+                   {\r
+                     /* Don't consider final '\n' to be part of comment.  */\r
+                     cppReader_forward (pfile, -1);\r
+                     /*@loopbreak@*/ break;\r
+                   }\r
+               }\r
+             c = '-';\r
+             goto return_comment;\r
+           }\r
+         if (c2 == '-' || c2 == '=' || c2 == '>')\r
+           goto op2;\r
+         goto randomchar;\r
+\r
+       case '<':\r
+         if (pfile->parsing_include_directive)\r
+           {\r
+             for (;;)\r
+               {\r
+                 cppReader_putChar (pfile, c);\r
+                 if (c == '>')\r
+                   /*@loopbreak@*/ break;\r
+                 c = cppReader_getC (pfile);\r
+                 NEWLINE_FIX1 (c);\r
+                 if (c == '\n' || c == EOF)\r
+                   {\r
+                     cppReader_errorLit (pfile,\r
+                                   cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));\r
+                     /*@loopbreak@*/ break;\r
+                   }\r
+               }\r
+             return CPP_STRING;\r
+           }\r
+         /*@fallthrough@*/\r
+       case '>':\r
+         NEWLINE_FIX;\r
+         c2 = cppReader_peekC (pfile);\r
+         if (c2 == '=')\r
+           goto op2;\r
+         if (c2 != c)\r
+           goto randomchar;\r
+         cppReader_forward (pfile, 1);\r
+         cppReader_reserve (pfile, 4);\r
+         cppReader_putChar (pfile, c);\r
+         cppReader_putChar (pfile, c2);\r
+         NEWLINE_FIX;\r
+         c3 = cppReader_peekC (pfile);\r
+         if (c3 == '=')\r
+           cppReader_putCharQ (pfile, cppReader_getC (pfile));\r
+         cppReader_nullTerminateQ (pfile);\r
+         pfile->only_seen_white = 0;\r
+         return CPP_OTHER;\r
+\r
+       case '@':\r
+         if (cppReader_getBuffer (pfile)->has_escapes)\r
+           {\r
+             c = cppReader_getC (pfile);\r
+             if (c == '-')\r
+               {\r
+                 if (pfile->output_escapes)\r
+                   cppReader_puts (pfile, "@-", 2);\r
+                 parse_name (pfile, cppReader_getC (pfile));\r
+                 return CPP_NAME;\r
+               }\r
+             else if (is_space [c])\r
+               {\r
+                 cppReader_reserve (pfile, 2);\r
+                 if (pfile->output_escapes)\r
+                   cppReader_putCharQ (pfile, '@');\r
+                 cppReader_putCharQ (pfile, c);\r
+                 return CPP_HSPACE;\r
+               }\r
+             else\r
+               {\r
+                 ;\r
+               }\r
+           }\r
+         if (pfile->output_escapes)\r
+           {\r
+             cppReader_puts (pfile, "@@", 2);\r
+             return CPP_OTHER;\r
+           }\r
+         goto randomchar;\r
+       case '.':\r
+         NEWLINE_FIX;\r
+         c2 = cppReader_peekC (pfile);\r
+         if (isdigit(c2))\r
+           {\r
+             cppReader_reserve(pfile, 2);\r
+             cppReader_putCharQ (pfile, '.');\r
+             c = cppReader_getC (pfile);\r
+             goto number;\r
+           }\r
+\r
+         /* FIXME - misses the case "..\\\n." */\r
+         if (c2 == '.' && cpp_peekN (pfile, 1) == '.')\r
+           {\r
+             cppReader_reserve(pfile, 4);\r
+             cppReader_putCharQ (pfile, '.');\r
+             cppReader_putCharQ (pfile, '.');\r
+             cppReader_putCharQ (pfile, '.');\r
+             cppReader_forward (pfile, 2);\r
+             cppReader_nullTerminateQ (pfile);\r
+             pfile->only_seen_white = 0;\r
+             return CPP_3DOTS;\r
+           }\r
+         goto randomchar;\r
+       op2:\r
+         token = CPP_OTHER;\r
+         pfile->only_seen_white = 0;\r
+        op2any:\r
+         cppReader_reserve(pfile, 3);\r
+         cppReader_putCharQ (pfile, c);\r
+         cppReader_putCharQ (pfile, cppReader_getC (pfile));\r
+         cppReader_nullTerminateQ (pfile);\r
+         return token;\r
+\r
+       case 'L':\r
+         NEWLINE_FIX;\r
+         c2 = cppReader_peekC (pfile);\r
+         if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))\r
+           {\r
+             cppReader_putChar (pfile, c);\r
+             c = cppReader_getC (pfile);\r
+             goto string;\r
+           }\r
+         goto letter;\r
+\r
+       case '0': case '1': case '2': case '3': case '4':\r
+       case '5': case '6': case '7': case '8': case '9':\r
+       number:\r
+         c2  = '.';\r
+         for (;;)\r
+           {\r
+             cppReader_reserve (pfile, 2);\r
+             cppReader_putCharQ (pfile, c);\r
+             NEWLINE_FIX;\r
+             c = cppReader_peekC (pfile);\r
+             if (c == EOF)\r
+               /*@loopbreak@*/ break;\r
+             if (!is_idchar[c] && c != '.'\r
+                 && ((c2 != 'e' && c2 != 'E'\r
+                      && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))\r
+                     || (c != '+' && c != '-')))\r
+               /*@loopbreak@*/ break;\r
+             cppReader_forward (pfile, 1);\r
+             c2= c;\r
+           }\r
+\r
+         cppReader_nullTerminateQ (pfile);\r
+         pfile->only_seen_white = 0;\r
+         return CPP_NUMBER;\r
+\r
+       case 'b': case 'c': case 'd': case 'h': case 'o':\r
+       case 'B': case 'C': case 'D': case 'H': case 'O':\r
+         if (opts->chill && cppReader_peekC (pfile) == '\'')\r
+           {\r
+             pfile->only_seen_white = 0;\r
+             cppReader_reserve (pfile, 2);\r
+             cppReader_putCharQ (pfile, c);\r
+             cppReader_putCharQ (pfile, '\'');\r
+             cppReader_forward (pfile, 1);\r
+             for (;;)\r
+               {\r
+                 c = cppReader_getC (pfile);\r
+                 if (c == EOF)\r
+                   goto chill_number_eof;\r
+                 if (!is_idchar[c])\r
+                   {\r
+                     if (c == '\\' && cppReader_peekC (pfile) == '\n')\r
+                       {\r
+                         cppReader_forward (pfile, 2);\r
+                         continue;\r
+                       }\r
+                     /*@loopbreak@*/ break;\r
+                   }\r
+                 cppReader_putChar (pfile, c);\r
+               }\r
+             if (c == '\'')\r
+               {\r
+                 cppReader_reserve (pfile, 2);\r
+                 cppReader_putCharQ (pfile, c);\r
+                 cppReader_nullTerminateQ (pfile);\r
+                 return CPP_STRING;\r
+               }\r
+             else\r
+               {\r
+                 cppReader_forward (pfile, -1);\r
+               chill_number_eof:\r
+                 cppReader_nullTerminate (pfile);\r
+                 return CPP_NUMBER;\r
+               }\r
+           }\r
+         else\r
+           goto letter;\r
+       case '_':\r
+       case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':\r
+       case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':\r
+       case 'r': case 's': case 't': case 'u': case 'v': case 'w':\r
+       case 'x': case 'y': case 'z':\r
+       case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':\r
+       case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':\r
+       case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\r
+       case 'Y': case 'Z':\r
+        letter:\r
+          {\r
+           hashNode hp;\r
+           char *ident;\r
+           size_t before_name_written = cppReader_getWritten (pfile);\r
+           int ident_len;\r
+           parse_name (pfile, c);\r
+           pfile->only_seen_white = 0;\r
+           if (pfile->no_macro_expand)\r
+             {\r
+               return CPP_NAME;\r
+             }\r
+\r
+           ident = pfile->token_buffer + before_name_written;\r
+           ident_len = (cppReader_getPWritten (pfile)) - ident;\r
+\r
+           hp = cppReader_lookupExpand (ident, ident_len, -1);\r
+\r
+           if (hp == NULL)\r
+             {\r
+               return CPP_NAME;\r
+             }\r
+\r
+           if (hp->type == T_DISABLED)\r
+             {\r
+               if (pfile->output_escapes)\r
+                 { /* Return "@-IDENT", followed by '\0'.  */\r
+                   int i;\r
+                   cppReader_reserve (pfile, 3);\r
+                   ident = pfile->token_buffer + before_name_written;\r
+                   cppReader_adjustWritten (pfile, 2);\r
+\r
+                   for (i = ident_len; i >= 0; i--)\r
+                     {\r
+                       ident[i+2] = ident[i];\r
+                     }\r
+\r
+                   ident[0] = '@';\r
+                   ident[1] = '-';\r
+                 }\r
+               return CPP_NAME;\r
+             }\r
+\r
+           /* If macro wants an arglist, verify that a '(' follows.\r
+              first skip all whitespace, copying it to the output\r
+              after the macro name.  Then, if there is no '(',\r
+              decide this is not a macro call and leave things that way.  */\r
+\r
+           if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)\r
+             {\r
+               struct parse_marker macro_mark;\r
+               int is_macro_call;\r
+\r
+               while (cppBuffer_isMacro (CPPBUFFER (pfile)))\r
+                 {\r
+                   cppBuffer *next_buf;\r
+                   cppSkipHspace (pfile);\r
+                   if (cppReader_peekC (pfile) != EOF)\r
+                     {\r
+                       /*@loopbreak@*/ break;\r
+                     }\r
+\r
+                 next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));\r
+                 (*cppReader_getBuffer (pfile)->cleanup) (cppReader_getBuffer (pfile), pfile);\r
+                 CPPBUFFER (pfile) = next_buf;\r
+                 }\r
+\r
+               parseSetMark (&macro_mark, pfile);\r
+\r
+               for (;;)\r
+                 {\r
+                   cppSkipHspace (pfile);\r
+                   c = cppReader_peekC (pfile);\r
+                   is_macro_call = c == '(';\r
+                   if (c != '\n')\r
+                     /*@loopbreak@*/ break;\r
+                   cppReader_forward (pfile, 1);\r
+                 }\r
+\r
+               if (!is_macro_call)\r
+                 {\r
+                   parseGotoMark (&macro_mark, pfile);\r
+                 }\r
+\r
+               parseClearMark (&macro_mark);\r
+\r
+               if (!is_macro_call)\r
+                 {\r
+                   return CPP_NAME;\r
+                 }\r
+             }\r
+           /* This is now known to be a macro call.  */\r
+\r
+           /* it might not actually be a macro.  */\r
+           if (hp->type != T_MACRO)\r
+             {\r
+               size_t xbuf_len;\r
+               char *xbuf;\r
+\r
+               cppReader_setWritten (pfile, before_name_written);\r
+               special_symbol (hp, pfile);\r
+               xbuf_len = cppReader_getWritten (pfile) - before_name_written;\r
+               xbuf = (char *) dmalloc (xbuf_len + 1);\r
+               cppReader_setWritten (pfile, before_name_written);\r
+               memcpy (xbuf, cppReader_getPWritten (pfile), xbuf_len + 1);\r
+               push_macro_expansion (pfile, xbuf, xbuf_len, hp);\r
+             }\r
+           else\r
+             {\r
+               /* Expand the macro, reading arguments as needed,\r
+                  and push the expansion on the input stack.  */\r
+                               macroexpand (pfile, hp);\r
+               cppReader_setWritten (pfile, before_name_written);\r
+             }\r
+\r
+           /* An extra "@ " is added to the end of a macro expansion\r
+              to prevent accidental token pasting.  We prefer to avoid\r
+              unneeded extra spaces (for the sake of cpp-using tools like\r
+              imake).  Here we remove the space if it is safe to do so.  */\r
+\r
+           llassert (pfile->buffer->rlimit != NULL);\r
+\r
+           if (pfile->buffer->rlimit - pfile->buffer->cur >= 3\r
+               && pfile->buffer->rlimit[-2] == '@'\r
+               && pfile->buffer->rlimit[-1] == ' ')\r
+             {\r
+               int c1 = pfile->buffer->rlimit[-3];\r
+               int cl2 = cppBufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));\r
+\r
+               if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))\r
+                 pfile->buffer->rlimit -= 2;\r
+             }\r
+         }\r
+         goto get_next;\r
+\r
+\r
+       case ' ':  case '\t':  case '\v':  case '\r':\r
+         for (;;)\r
+           {\r
+             cppReader_putChar (pfile, c);\r
+             c = cppReader_peekC (pfile);\r
+             if (c == EOF || !is_hor_space[c])\r
+               /*@loopbreak@*/ break;\r
+             cppReader_forward (pfile, 1);\r
+           }\r
+         return CPP_HSPACE;\r
+\r
+        case '\\':\r
+         c2 = cppReader_peekC (pfile);\r
+         if (c2 != '\n')\r
+           goto randomchar;\r
+         token = CPP_HSPACE;\r
+         goto op2any;\r
+\r
+       case '\n':\r
+         cppReader_putChar (pfile, c);\r
+         if (pfile->only_seen_white == 0)\r
+           pfile->only_seen_white = 1;\r
+         pfile->lineno++;\r
+         output_line_command (pfile, 1, same_file);\r
+         return CPP_VSPACE;\r
+\r
+       case '(': token = CPP_LPAREN;    goto char1;\r
+       case ')': token = CPP_RPAREN;    goto char1;\r
+       case '{': token = CPP_LBRACE;    goto char1;\r
+       case '}': token = CPP_RBRACE;    goto char1;\r
+       case ',': token = CPP_COMMA;     goto char1;\r
+       case ';': token = CPP_SEMICOLON; goto char1;\r
+\r
+       randomchar:\r
+       default:\r
+         token = CPP_OTHER;\r
+       char1:\r
+         pfile->only_seen_white = 0;\r
+         cppReader_putChar (pfile, c);\r
+         return token;\r
+       }\r
+    }\r
+\r
+  BADBRANCH;\r
+  /*@notreached@*/\r
+}\r
+\r
+/* Parse an identifier starting with C.  */\r
+\r
+void\r
+parse_name (cppReader *pfile, int c)\r
+{\r
+  for (;;)\r
+    {\r
+      if (!is_idchar[c])\r
+       {\r
+         if (c == '\\' && cppReader_peekC (pfile) == '\n')\r
+           {\r
+             cppReader_forward (pfile, 2);\r
+             continue;\r
+           }\r
+\r
+         cppReader_forward (pfile, -1);\r
+         break;\r
+       }\r
+\r
+      if (c == '$' && cppReader_isPedantic (pfile))\r
+       {\r
+         cppReader_pedwarnLit (pfile,\r
+                         cstring_makeLiteralTemp ("`$' in identifier"));\r
+       }\r
+\r
+      cppReader_reserve(pfile, 2); /* One more for final NUL.  */\r
+      cppReader_putCharQ (pfile, c);\r
+      c = cppReader_getC (pfile);\r
+\r
+      if (c == EOF)\r
+       break;\r
+    }\r
+\r
+  cppReader_nullTerminateQ (pfile);\r
+}\r
+\r
+/* The file_name_map structure holds a mapping of file names for a\r
+   particular directory.  This mapping is read from the file named\r
+   FILE_NAME_MAP_FILE in that directory.  Such a file can be used to\r
+   map filenames on a file system with severe filename restrictions,\r
+   such as DOS.  The format of the file name map file is just a series\r
+   of lines with two tokens on each line.  The first token is the name\r
+   to map, and the second token is the actual name to use.  */\r
+\r
+struct file_name_map\r
+{\r
+  struct file_name_map *map_next;\r
+  cstring map_from;\r
+  cstring map_to;\r
+};\r
+\r
+/*@constant observer char *FILE_NAME_MAP_FILE*/\r
+#define FILE_NAME_MAP_FILE "header.gcc"\r
+\r
+/* Read a space delimited string of unlimited length from a stdio\r
+   file.  */\r
+\r
+static cstring read_filename_string (int ch, /*:open:*/ FILE *f)\r
+{\r
+  char *alloc, *set;\r
+  size_t len;\r
+\r
+  len = 20;\r
+  set = alloc = dmalloc (len + 1);\r
+\r
+  if (!is_space[ch])\r
+    {\r
+      *set++ = ch;\r
+      while ((ch = getc (f)) != EOF && ! is_space[ch])\r
+       {\r
+         if (set - alloc == size_toInt (len))\r
+           {\r
+             len *= 2;\r
+             alloc = drealloc (alloc, len + 1);\r
+             set = alloc + len / 2;\r
+             /*@-branchstate@*/ }\r
+\r
+         *set++ = ch;\r
+       } /*@=branchstate@*/\r
+    }\r
+  *set = '\0';\r
+  check (ungetc (ch, f) != EOF);\r
+\r
+  return cstring_fromChars (alloc);\r
+}\r
+\r
+/* This structure holds a linked list of file name maps, one per directory.  */\r
+\r
+struct file_name_map_list\r
+{\r
+  struct file_name_map_list *map_list_next;\r
+  cstring map_list_name;\r
+  struct file_name_map *map_list_map;\r
+};\r
+\r
+/* Read the file name map file for DIRNAME.  */\r
+\r
+static struct file_name_map *\r
+read_name_map (cppReader *pfile, cstring dirname)\r
+{\r
+  struct file_name_map_list *map_list_ptr;\r
+  cstring name;\r
+  FILE *f;\r
+\r
+  for (map_list_ptr = CPPOPTIONS (pfile)->map_list;\r
+       map_list_ptr != NULL;\r
+       map_list_ptr = map_list_ptr->map_list_next)\r
+    {\r
+      if (cstring_equal (map_list_ptr->map_list_name, dirname))\r
+       {\r
+         return map_list_ptr->map_list_map;\r
+       }\r
+    }\r
+\r
+  map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));\r
+  map_list_ptr->map_list_name = cstring_copy (dirname);\r
+  map_list_ptr->map_list_map = NULL;\r
+\r
+  name = cstring_copy (dirname);\r
+\r
+  if (cstring_length (dirname) > 0)\r
+    {\r
+      name = cstring_appendChar (name, CONNECTCHAR);\r
+    }\r
+\r
+  name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));\r
+\r
+  f = fileTable_openFile (context_fileTable (), name, "r");\r
+  cstring_free (name);\r
+\r
+  if (f == NULL)\r
+    {\r
+      map_list_ptr->map_list_map = NULL;\r
+    }\r
+  else\r
+    {\r
+      int ch;\r
+\r
+      while ((ch = getc (f)) != EOF)\r
+       {\r
+         cstring from, to;\r
+         struct file_name_map *ptr;\r
+\r
+         if (is_space[ch])\r
+           {\r
+             continue;\r
+           }\r
+\r
+         from = read_filename_string (ch, f);\r
+         while ((ch = getc (f)) != EOF && is_hor_space[ch])\r
+           {\r
+             ;\r
+           }\r
+\r
+         to = read_filename_string (ch, f);\r
+\r
+         ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));\r
+         ptr->map_from = from;\r
+\r
+         /* Make the real filename absolute.  */\r
+         if (cstring_length (to) > 1 \r
+             && osd_isConnectChar (cstring_firstChar (to)))\r
+           {\r
+             ptr->map_to = to;\r
+           }\r
+         else\r
+           {\r
+             ptr->map_to = cstring_copy (dirname);\r
+             ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);\r
+             ptr->map_to = cstring_concatFree (ptr->map_to, to);\r
+           }\r
+\r
+         ptr->map_next = map_list_ptr->map_list_map;\r
+         map_list_ptr->map_list_map = ptr;\r
+\r
+         while ((ch = getc (f)) != '\n')\r
+           {\r
+             if (ch == EOF)\r
+               {\r
+                 /*@innerbreak@*/ break;\r
+               }\r
+           }\r
+       }\r
+\r
+      assertSet (map_list_ptr->map_list_map);\r
+      check (fileTable_closeFile (context_fileTable (),f) == 0);\r
+    }\r
+\r
+  map_list_ptr->map_list_next = pfile->opts->map_list;\r
+  pfile->opts->map_list = map_list_ptr;\r
+\r
+  return map_list_ptr->map_list_map;\r
+}\r
+\r
+/* Try to open include file FILENAME.  SEARCHPTR is the directory\r
+   being tried from the include file search path.  This function maps\r
+   filenames on file systems based on information read by\r
+   read_name_map.  */\r
+\r
+static int\r
+open_include_file (cppReader *pfile,\r
+                  cstring fname,\r
+                  struct file_name_list *searchptr)\r
+{\r
+  char *filename = cstring_toCharsSafe (fname);\r
+  struct file_name_map *map;\r
+  char *from;\r
+  char *p, *dir;\r
+\r
+  cstring_markOwned (fname);\r
+\r
+  cpp_setLocation (pfile);\r
+\r
+  if (context_getFlag (FLG_NEVERINCLUDE))\r
+    {\r
+      if (isHeaderFile (fname))\r
+       {\r
+         return SKIP_INCLUDE;\r
+       }\r
+    }\r
+\r
+  if ((searchptr != NULL) && ! searchptr->got_name_map)\r
+    {\r
+      searchptr->name_map = read_name_map (pfile,\r
+                                          !cstring_isEmpty (searchptr->fname)\r
+                                          ? searchptr->fname :\r
+                                          cstring_makeLiteralTemp ("."));\r
+      searchptr->got_name_map = 1;\r
+    }\r
+\r
+  /* First check the mapping for the directory we are using.  */\r
+\r
+  if ((searchptr != NULL)\r
+      && (searchptr->name_map != NULL))\r
+    {\r
+      from = filename;\r
+\r
+      if (!cstring_isEmpty (searchptr->fname))\r
+       {\r
+         from += cstring_length (searchptr->fname) + 1;\r
+       }\r
+\r
+      for (map = searchptr->name_map;\r
+          map != NULL;\r
+          map = map->map_next)\r
+       {\r
+         if (cstring_equal (map->map_from, cstring_fromChars (from)))\r
+           {\r
+             /*\r
+             ** Found a match.  Check if the file should be skipped\r
+             */\r
+             \r
+             if (cpp_skipIncludeFile (map->map_to))\r
+               {\r
+                 return SKIP_INCLUDE;\r
+               }\r
+             else\r
+               {\r
+                 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));\r
+               }\r
+           }\r
+       }\r
+    }\r
+\r
+  /*\r
+  ** Try to find a mapping file for the particular directory we are\r
+  ** looking in.  Thus #include <sys/types.h> will look up sys/types.h\r
+  ** in /usr/include/header.gcc and look up types.h in\r
+  ** /usr/include/sys/header.gcc.\r
+  */\r
+\r
+  p = strrchr (filename, CONNECTCHAR);\r
+\r
+  if (p == NULL)\r
+    {\r
+      p = filename;\r
+    }\r
+\r
+  if ((searchptr != NULL)\r
+      && (cstring_isDefined (searchptr->fname))\r
+      && (cstring_length (searchptr->fname) == p - filename)\r
+      && !strncmp (cstring_toCharsSafe (searchptr->fname),\r
+                  filename,\r
+                  size_fromInt (p - filename)))\r
+    {\r
+      /* filename is in SEARCHPTR, which we've already checked.  */\r
+\r
+      if (cpp_skipIncludeFile (cstring_fromChars (filename)))\r
+       {\r
+         return SKIP_INCLUDE;\r
+       }\r
+      else\r
+       {\r
+         return cpp_openIncludeFile (filename);\r
+       }\r
+    }\r
+\r
+  if (p == filename)\r
+    {\r
+      dir = mstring_copy (".");\r
+      from = filename;\r
+    }\r
+  else\r
+    {\r
+      dir = (char *) dmalloc (size_fromInt (p - filename + 1));\r
+      memcpy (dir, filename, size_fromInt (p - filename));\r
+      dir[p - filename] = '\0';\r
+      from = p + 1;\r
+    }\r
+\r
+  for (map = read_name_map (pfile, cstring_fromChars (dir));\r
+       map != NULL;\r
+       map = map->map_next)\r
+    {\r
+      if (cstring_equal (map->map_from, cstring_fromChars (from)))\r
+       {\r
+         sfree (dir);\r
+\r
+         if (cpp_skipIncludeFile (map->map_to))\r
+           {\r
+             return SKIP_INCLUDE;\r
+           }\r
+         else\r
+           {\r
+             return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));\r
+           }\r
+       }\r
+    }\r
+\r
+  sfree (dir);\r
+\r
+  if (cpp_skipIncludeFile (cstring_fromChars (filename)))\r
+    {\r
+      return SKIP_INCLUDE;\r
+    }\r
+  else\r
+    {\r
+      return cpp_openIncludeFile (filename);\r
+    }\r
+}\r
+\r
+/* Process the contents of include file FNAME, already open on descriptor F,\r
+   with output to OP.\r
+   SYSTEM_HEADER_P is 1 if this file resides in any one of the known\r
+   "system" include directories (as decided by the `is_system_include'\r
+   function above).\r
+   DIRPTR is the link in the dir path through which this file was found,\r
+   or 0 if the file name was absolute or via the current directory.\r
+   Return 1 on success, 0 on failure.\r
+\r
+   The caller is responsible for the cppReader_pushBuffer.  */\r
+\r
+static int\r
+finclude (cppReader *pfile, int f,\r
+         cstring fname,\r
+         bool system_header_p,\r
+         /*@dependent@*/ struct file_name_list *dirptr)\r
+{\r
+  mode_t st_mode;\r
+  size_t st_size;\r
+  long i;\r
+  int length = 0;\r
+  cppBuffer *fp;                       /* For input stack frame */\r
+\r
+  if (file_size_and_mode (f, &st_mode, &st_size) < 0)\r
+    {\r
+      cppReader_perrorWithName (pfile, fname);\r
+      check (close (f) == 0);\r
+      (void) cppReader_popBuffer (pfile);\r
+      /*@-mustfree@*/\r
+      return 0;\r
+      /*@=mustfree@*/\r
+    }\r
+\r
+  fp = cppReader_getBuffer (pfile);\r
+\r
+  /*@-temptrans@*/ /* fname shouldn't really be temp */\r
+  fp->nominal_fname = fp->fname = fname;\r
+  /*@=temptrans@*/\r
+\r
+  fp->dir = dirptr;\r
+  fp->system_header_p = system_header_p;\r
+  fp->lineno = 1;\r
+  fp->colno = 1;\r
+  fp->cleanup = cppReader_fileCleanup;\r
+\r
+  if (S_ISREG (st_mode))\r
+    {\r
+      sfree (fp->buf);\r
+      fp->buf = (char *) dmalloc (st_size + 2);\r
+      fp->alimit = fp->buf + st_size + 2;\r
+      fp->cur = fp->buf;\r
+\r
+      /* Read the file contents, knowing that st_size is an upper bound\r
+        on the number of bytes we can read.  */\r
+      length = safe_read (f, fp->buf, size_toInt (st_size));\r
+      fp->rlimit = fp->buf + length;\r
+      if (length < 0) goto nope;\r
+    }\r
+  else if (S_ISDIR (st_mode))\r
+    {\r
+      cppReader_error (pfile,\r
+                      message ("Directory specified in #include: %s", fname));\r
+      check (close (f) == 0);\r
+      return 0;\r
+    }\r
+  else\r
+    {\r
+      /*\r
+      ** Cannot count its file size before reading.\r
+      ** First read the entire file into heap and\r
+      ** copy them into buffer on stack.\r
+      */\r
+\r
+      size_t bsize = 2000;\r
+\r
+      st_size = 0;\r
+\r
+      sfree (fp->buf);\r
+      fp->buf = (char *) dmalloc (bsize + 2);\r
+\r
+      for (;;) {\r
+       i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));\r
+\r
+       if (i < 0)\r
+         goto nope;      /* error! */\r
+       st_size += i;\r
+\r
+       if (st_size != bsize)\r
+         {\r
+           break;      /* End of file */\r
+         }\r
+\r
+       bsize *= 2;\r
+       fp->buf = (char *) drealloc (fp->buf, bsize + 2);\r
+      }\r
+\r
+      fp->cur = fp->buf;\r
+      length = size_toInt (st_size);\r
+    }\r
+\r
+  if ((length > 0 && fp->buf[length - 1] != '\n')\r
+      /* Backslash-newline at end is not good enough.  */\r
+      || (length > 1 && fp->buf[length - 2] == '\\')) {\r
+    fp->buf[length++] = '\n';\r
+  }\r
+\r
+  fp->buf[length] = '\0';\r
+  fp->rlimit = fp->buf + length;\r
+\r
+  /* Close descriptor now, so nesting does not use lots of descriptors.  */\r
+  check (close (f) == 0);\r
+\r
+  /* Must do this before calling trigraph_pcp, so that the correct file name\r
+     will be printed in warning messages.  */\r
+\r
+  pfile->input_stack_listing_current = 0;\r
+  return 1;\r
+\r
+ nope:\r
+\r
+  cppReader_perrorWithName (pfile, fname);\r
+  check (close (f) == 0);\r
+  sfree (fp->buf);\r
+  return 1;\r
+}\r
+\r
+void\r
+cppReader_init (cppReader *pfile)\r
+{\r
+  memset ((char *) pfile, 0, sizeof (*pfile));\r
+\r
+  pfile->get_token = cppGetToken;\r
+  pfile->token_buffer_size = 200;\r
+  pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);\r
+  pfile->all_include_files = NULL;\r
+\r
+  assertSet (pfile);\r
+\r
+  cppReader_setWritten (pfile, 0);\r
+\r
+  pfile->system_include_depth = 0;\r
+  pfile->max_include_len = 0;\r
+  pfile->timebuf = NULL;\r
+  pfile->only_seen_white = 1;\r
+\r
+  pfile->buffer = cppReader_nullBuffer (pfile);\r
+}\r
+\r
+void\r
+cppReader_finish (/*@unused@*/ cppReader *pfile)\r
+{\r
+  ;\r
+}\r
+\r
+/* Free resources used by PFILE.\r
+   This is the cppReader 'finalizer' or 'destructor' (in C++ terminology).  */\r
+\r
+void\r
+cppCleanup (cppReader *pfile)\r
+{\r
+  while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))\r
+    {\r
+      (void) cppReader_popBuffer (pfile);\r
+    }\r
+\r
+  if (pfile->token_buffer != NULL)\r
+    {\r
+      sfree (pfile->token_buffer);\r
+      pfile->token_buffer = NULL;\r
+    }\r
+\r
+  while (pfile->if_stack != NULL)\r
+    {\r
+      cppIfStackFrame *temp = pfile->if_stack;\r
+      pfile->if_stack = temp->next;\r
+      sfree (temp);\r
+    }\r
+\r
+  while (pfile->all_include_files != NULL)\r
+    {\r
+      struct file_name_list *temp = pfile->all_include_files;\r
+      pfile->all_include_files = temp->next;\r
+      /*@-dependenttrans@*/\r
+      cstring_free (temp->fname);\r
+      /*@=dependenttrans@*/\r
+      sfree (temp);\r
+    }\r
+\r
+  cppReader_hashCleanup ();\r
+}\r
+\r
+/*\r
+** Get the file-mode and data size of the file open on FD\r
+** and store them in *MODE_POINTER and *SIZE_POINTER.\r
+*/\r
+\r
+static int\r
+file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)\r
+{\r
+  struct stat sbuf;\r
+\r
+  if (fstat (fd, &sbuf) < 0) {\r
+    return (-1);\r
+  }\r
+\r
+  if (mode_pointer != NULL)\r
+    {\r
+      *mode_pointer = sbuf.st_mode;\r
+    }\r
+\r
+  if (size_pointer != NULL)\r
+    {\r
+      *size_pointer = (size_t) sbuf.st_size;\r
+    }\r
+\r
+  return 0;\r
+}\r
+\r
+/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,\r
+   retrying if necessary.  Return a negative value if an error occurs,\r
+   otherwise return the actual number of bytes read,\r
+   which must be LEN unless end-of-file was reached.  */\r
+\r
+static int safe_read (int desc, char *ptr, int len)\r
+{\r
+  int left = len;\r
+\r
+  while (left > 0)\r
+    {\r
+# if defined (WIN32) || defined (OS2) && defined (__IBMC__)\r
+         /*@-compdef@*/ /* ptr is an out parameter */\r
+      int nchars = _read (desc, ptr, (unsigned) left);\r
+         /*@=compdef@*/\r
+# else\r
+      ssize_t nchars = read (desc, ptr, size_fromInt (left));\r
+# endif\r
+\r
+      if (nchars < 0)\r
+       {\r
+#ifdef EINTR\r
+         if (errno == EINTR)\r
+           continue;\r
+#endif\r
+         return (int) nchars;\r
+       }\r
+\r
+      if (nchars == 0) {\r
+       break;\r
+      }\r
+\r
+      ptr += nchars;\r
+      left -= nchars;\r
+    }\r
+\r
+  return len - left;\r
+}\r
+\r
+/* Initialize PMARK to remember the current position of PFILE.  */\r
+\r
+void\r
+parseSetMark (struct parse_marker *pmark, cppReader *pfile)\r
+{\r
+  cppBuffer *pbuf = cppReader_getBuffer (pfile);\r
+\r
+  pmark->next = pbuf->marks;\r
+  /*@-temptrans@*/\r
+  pbuf->marks = pmark;\r
+  /*@=temptrans@*/\r
+\r
+  pmark->buf = pbuf;\r
+  pmark->position = pbuf->cur - pbuf->buf;\r
+}\r
+\r
+/* Cleanup PMARK - we no longer need it.  */\r
+\r
+void parseClearMark (struct parse_marker *pmark)\r
+{\r
+  struct parse_marker **pp = &pmark->buf->marks;\r
+\r
+  for (; ; pp = &(*pp)->next)\r
+    {\r
+      llassert (*pp != NULL);\r
+      if (*pp == pmark) break;\r
+    }\r
+\r
+  *pp = pmark->next;\r
+}\r
+\r
+/* Backup the current position of PFILE to that saved in PMARK.  */\r
+\r
+void\r
+parseGotoMark (struct parse_marker *pmark, cppReader *pfile)\r
+{\r
+  cppBuffer *pbuf = cppReader_getBuffer (pfile);\r
+\r
+  if (pbuf != pmark->buf)\r
+    {\r
+      cpp_setLocation (pfile);\r
+      llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));\r
+    }\r
+\r
+  llassert (pbuf->buf != NULL);\r
+  pbuf->cur = pbuf->buf + pmark->position;\r
+}\r
+\r
+/* Reset PMARK to point to the current position of PFILE.  (Same\r
+   as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster.  */\r
+\r
+void\r
+parseMoveMark (struct parse_marker *pmark, cppReader *pfile)\r
+{\r
+  cppBuffer *pbuf = cppReader_getBuffer (pfile);\r
+\r
+  if (pbuf != pmark->buf)\r
+    {\r
+      cpp_setLocation (pfile);\r
+      llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));\r
+    }\r
+\r
+  pmark->position = pbuf->cur - pbuf->buf;\r
+}\r
+\r
+void cppReader_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */\r
+{\r
+  struct cppOptions *opts = CPPOPTIONS (pfile);\r
+  cstring xp;\r
+\r
+  /* The code looks at the defaults through this pointer, rather than through\r
+     the constant structure above.  This pointer gets changed if an environment\r
+     variable specifies other defaults.  */\r
+\r
+  struct default_include *include_defaults = include_defaults_array;\r
+\r
+  /* Add dirs from INCLUDEPATH_VAR after dirs from -I.  */\r
+  /* There seems to be confusion about what CPATH should do,\r
+     so for the moment it is not documented.  */\r
+  /* Some people say that CPATH should replace the standard include dirs,\r
+     but that seems pointless: it comes before them, so it overrides them\r
+     anyway.  */\r
+\r
+  xp = osd_getEnvironmentVariable (INCLUDEPATH_VAR);\r
+\r
+  if (cstring_isDefined (xp) && !opts->no_standard_includes)\r
+    {\r
+      path_include (pfile, cstring_toCharsSafe (xp));\r
+    }\r
+\r
+  /* Now that dollars_in_ident is known, initialize is_idchar.  */\r
+  initialize_char_syntax (opts);\r
+\r
+  /* CppReader_Install __LINE__, etc.  Must follow initialize_char_syntax\r
+     and option processing.  */\r
+\r
+  initialize_builtins (pfile);\r
+\r
+  /* Do standard #defines and assertions\r
+     that identify system and machine type.  */\r
+\r
+  if (!opts->inhibit_predefs) {\r
+    char *p = (char *) dmalloc (strlen (predefs) + 1);\r
+    strcpy (p, predefs);\r
+\r
+    while (*p)\r
+      {\r
+       char *q;\r
+\r
+       while (*p == ' ' || *p == '\t')\r
+         {\r
+           p++;\r
+         }\r
+\r
+       /* Handle -D options.  */\r
+       if (p[0] == '-' && p[1] == 'D')\r
+         {\r
+           q = &p[2];\r
+\r
+           while (*p && *p != ' ' && *p != '\t')\r
+             {\r
+               p++;\r
+             }\r
+\r
+           if (*p != 0)\r
+             {\r
+               *p++= 0;\r
+             }\r
+\r
+           if (opts->debug_output)\r
+             {\r
+               output_line_command (pfile, 0, same_file);\r
+             }\r
+\r
+           cppReader_define (pfile, q);\r
+\r
+           while (*p == ' ' || *p == '\t')\r
+             {\r
+               p++;\r
+             }\r
+         }\r
+       else\r
+         {\r
+           abort ();\r
+         }\r
+      }\r
+\r
+    sfree (p);\r
+  }\r
+\r
+  opts->done_initializing = 1;\r
+\r
+  { /* Read the appropriate environment variable and if it exists\r
+       replace include_defaults with the listed path.  */\r
+    char *epath = 0;\r
+#ifdef __CYGWIN32__\r
+  char *win32epath;\r
+  int win32_buf_size = 0; /* memory we need to allocate */\r
+#endif\r
+\r
+  if (opts->cplusplus)\r
+    {\r
+      epath = getenv ("CPLUS_INCLUDE_PATH");\r
+    }\r
+  else\r
+    {\r
+      epath = getenv ("C_INCLUDE_PATH");\r
+    }\r
+\r
+  /*\r
+  ** If the environment var for this language is set,\r
+  ** add to the default list of include directories.\r
+  */\r
+\r
+    if (epath != NULL) {\r
+      char *nstore = (char *) dmalloc (strlen (epath) + 2);\r
+      int num_dirs;\r
+      char *startp, *endp;\r
+\r
+#ifdef __CYGWIN32__\r
+      /* if we have a posix path list, convert to win32 path list */\r
+      if (cygwin32_posix_path_list_p (epath))\r
+        {\r
+          win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);\r
+          win32epath = (char *) dmalloc /*@i4@*/ (win32_buf_size);\r
+          cygwin32_posix_to_win32_path_list (epath, win32epath);\r
+          epath = win32epath;\r
+        }\r
+#endif\r
+      for (num_dirs = 1, startp = epath; *startp; startp++)\r
+       {\r
+         if (*startp == PATH_SEPARATOR)\r
+           num_dirs++;\r
+       }\r
+\r
+      /*@-sizeoftype@*/\r
+      include_defaults\r
+       = (struct default_include *) dmalloc ((num_dirs\r
+                                              * sizeof (struct default_include))\r
+                                             + sizeof (include_defaults_array));\r
+      /*@=sizeoftype@*/\r
+\r
+      startp = endp = epath;\r
+      num_dirs = 0;\r
+      while (1) {\r
+        /* Handle cases like c:/usr/lib:d:/gcc/lib */\r
+        if ((*endp == PATH_SEPARATOR) || *endp == 0)\r
+         {\r
+           strncpy (nstore, startp, size_fromInt (endp - startp));\r
+           if (endp == startp)\r
+             {\r
+               strcpy (nstore, ".");\r
+             }\r
+           else\r
+             {\r
+               nstore[endp-startp] = '\0';\r
+             }\r
+\r
+           include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);\r
+           include_defaults[num_dirs].cplusplus = opts->cplusplus;\r
+           include_defaults[num_dirs].cxx_aware = 1;\r
+           num_dirs++;\r
+\r
+           if (*endp == '\0')\r
+             {\r
+               break;\r
+             }\r
+           endp = startp = endp + 1;\r
+         }\r
+       else\r
+         {\r
+           endp++;\r
+         }\r
+      }\r
+      /* Put the usual defaults back in at the end.  */\r
+      memcpy ((char *) &include_defaults[num_dirs],\r
+             (char *) include_defaults_array,\r
+             sizeof (include_defaults_array));\r
+\r
+      sfree (nstore);\r
+      /*@-branchstate@*/ } /*@=branchstate@*/\r
+  }\r
+\r
+  cppReader_appendIncludeChain (pfile, opts->before_system,\r
+                               opts->last_before_system);\r
+  opts->first_system_include = opts->before_system;\r
+\r
+  /* Unless -fnostdinc,\r
+     tack on the standard include file dirs to the specified list */\r
+  if (!opts->no_standard_includes) {\r
+    struct default_include *p = include_defaults;\r
+    char *specd_prefix = opts->include_prefix;\r
+    char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);\r
+    int default_len = 0;\r
+\r
+       /* Remove the `include' from /usr/local/lib/gcc.../include.  */\r
+       if (default_prefix != NULL) {\r
+    if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {\r
+      default_len = strlen (default_prefix) - 7;\r
+      default_prefix[default_len] = 0;\r
+    }\r
+       }\r
+\r
+    /* Search "translated" versions of GNU directories.\r
+       These have /usr/local/lib/gcc... replaced by specd_prefix.  */\r
+    if (specd_prefix != 0 && default_len != 0)\r
+      for (p = include_defaults; p->fname != NULL; p++) {\r
+       /* Some standard dirs are only for C++.  */\r
+       if (!p->cplusplus\r
+           || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {\r
+         /* Does this dir start with the prefix?  */\r
+         if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix,\r
+                       size_fromInt (default_len)))\r
+           {\r
+             /* Yes; change prefix and add to search list.  */\r
+             struct file_name_list *nlist\r
+               = (struct file_name_list *) dmalloc (sizeof (*nlist));\r
+             size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;\r
+             char *str = (char *) dmalloc (this_len + 1);\r
+             strcpy (str, specd_prefix);\r
+             strcat (str, cstring_toCharsSafe (p->fname) + default_len);\r
+\r
+             nlist->next = NULL;\r
+             nlist->fname = cstring_fromChars (str);\r
+             nlist->control_macro = 0;\r
+             nlist->c_system_include_path = !p->cxx_aware;\r
+             nlist->got_name_map = 0;\r
+\r
+             cppReader_addIncludeChain (pfile, nlist);\r
+             if (opts->first_system_include == 0)\r
+               {\r
+                 opts->first_system_include = nlist;\r
+               }\r
+           }\r
+       }\r
+      }\r
+\r
+    /* Search ordinary names for GNU include directories.  */\r
+\r
+    for (p = include_defaults; p->fname != NULL; p++)\r
+      {\r
+       /* Some standard dirs are only for C++.  */\r
+       if (!p->cplusplus\r
+           || (opts->cplusplus && !opts->no_standard_cplusplus_includes))\r
+         {\r
+           struct file_name_list *nlist\r
+             = (struct file_name_list *) dmalloc (sizeof (*nlist));\r
+           nlist->control_macro = 0;\r
+           nlist->c_system_include_path = !p->cxx_aware;\r
+           nlist->fname = p->fname;\r
+           nlist->got_name_map = 0;\r
+           nlist->next = NULL;\r
+\r
+           cppReader_addIncludeChain (pfile, nlist);\r
+\r
+           if (opts->first_system_include == 0)\r
+             {\r
+               opts->first_system_include = nlist;\r
+             }\r
+         }\r
+      }\r
+    sfree (default_prefix);\r
+  }\r
+\r
+  /* Tack the after_include chain at the end of the include chain.  */\r
+  cppReader_appendIncludeChain (pfile, opts->after_include,\r
+                               opts->last_after_include);\r
+\r
+  if (opts->first_system_include == 0)\r
+    {\r
+      opts->first_system_include = opts->after_include;\r
+    }\r
+\r
+  /* With -v, print the list of dirs to search.  */\r
+  if (opts->verbose) {\r
+    struct file_name_list *p;\r
+    fprintf (stderr, "#include \"...\" search starts here:\n");\r
+\r
+    for (p = opts->include; p != NULL; p = p->next) {\r
+      if (p == opts->first_bracket_include)\r
+       fprintf (stderr, "#include <...> search starts here:\n");\r
+\r
+      fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));\r
+    }\r
+    fprintf (stderr, "End of search list.\n");\r
+  }\r
+}\r
+\r
+int cppReader_startProcess (cppReader *pfile, cstring fname)\r
+{\r
+  cppBuffer *fp;\r
+  int f;\r
+  struct cppOptions *opts = CPPOPTIONS (pfile);\r
+\r
+  fp = cppReader_pushBuffer (pfile, NULL, 0);\r
+\r
+  if (fp == NULL)\r
+    {\r
+      return 0;\r
+    }\r
+\r
+  if (opts->in_fname == NULL)\r
+    {\r
+      opts->in_fname = cstring_makeLiteralTemp ("");\r
+    }\r
+\r
+  fp->fname = opts->in_fname;\r
+  fp->nominal_fname = fp->fname;\r
+  fp->lineno = 0;\r
+\r
+  /* Copy the entire contents of the main input file into\r
+     the stacked input buffer previously allocated for it.  */\r
+\r
+  if (cstring_isEmpty (fname))\r
+    {\r
+      fname = cstring_makeLiteralTemp ("");\r
+      f = 0;\r
+    }\r
+  else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)\r
+    {\r
+      cppReader_error (pfile,\r
+                      message ("Error opening %s for reading: %s",\r
+                               fname, lldecodeerror (errno)));\r
+\r
+      return 0;\r
+    }\r
+  else\r
+    {\r
+      ;\r
+    }\r
+\r
+  if (finclude (pfile, f, fname, 0, NULL))\r
+    {\r
+      output_line_command (pfile, 0, same_file);\r
+    }\r
+\r
+  return 1;\r
+}\r
+\r
+static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)\r
+{\r
+  return pfile->buffer;\r
+}\r
+\r
+/*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)\r
+{\r
+  llassert (pfile->buffer != NULL);\r
+  return pfile->buffer;\r
+}\r
+\r
+/*@exposed@*/ char *cppLineBase (cppBuffer *buf)\r
+{\r
+  llassert (buf->buf != NULL);\r
+  return (buf->buf + buf->line_base);\r
+}\r
+\r
+int cppBufPeek (cppBuffer *buf)\r
+{\r
+  if (buf->cur == NULL || buf->rlimit == NULL) {\r
+    return EOF;\r
+  }\r
+\r
+  if (buf->cur < buf->rlimit) {\r
+    return *(buf->cur);\r
+  }\r
+\r
+  return EOF;\r
+}\r
+\r
+bool cppBuffer_isMacro (cppBuffer *buf)\r
+{\r
+  if (buf != NULL)\r
+    {\r
+      return (buf->cleanup == cppReader_macroCleanup);\r
+    }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/*\r
+** Returns true if the macro should be checked, false\r
+** if it should be expanded normally.\r
+*/\r
+\r
+static bool notparseable = FALSE;  /* preceeded by @notparseable@ */\r
+static bool notfunction = FALSE;   /* preceeded by @notfunction@ */\r
+static bool expectiter = FALSE;    /* preceeded by @iter@ */\r
+static bool expectenditer = FALSE; /* second after @iter@ */\r
+static bool expectfunction = FALSE;    /* preceeded by @function@ */\r
+static bool expectconstant = FALSE;   /* preceeded by @constant@ */\r
+static bool expectmacro = FALSE;   /* preceeded by notfunction or notparseable */\r
+\r
+static void cpp_setLocation (cppReader *pfile)\r
+{\r
+  fileId fid;\r
+  int line;\r
+\r
+  if (pfile->buffer != NULL)\r
+    {\r
+      if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname))\r
+       {\r
+         cstring fname = cppReader_getBuffer (pfile)->nominal_fname;\r
+         \r
+         DPRINTF (("Looking up: %s", fname));\r
+         \r
+         if (fileTable_exists (context_fileTable (), fname))\r
+           {\r
+             fid = fileTable_lookup (context_fileTable (), fname);\r
+           }\r
+         else\r
+           {\r
+             DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));\r
+\r
+             fid = fileTable_lookup (context_fileTable (),\r
+                                     cppReader_getBuffer (pfile)->fname);\r
+           }\r
+       }\r
+      else\r
+       {\r
+         fid = fileTable_lookup (context_fileTable (),\r
+                                 cppReader_getBuffer (pfile)->fname);\r
+       }\r
+      \r
+      line = cppReader_getBuffer (pfile)->lineno;\r
+      fileloc_free (g_currentloc);\r
+\r
+      if (fileId_isValid (fid))\r
+       {\r
+         g_currentloc = fileloc_create (fid, line, 1);\r
+       }\r
+      else\r
+       {\r
+         g_currentloc = fileloc_createBuiltin ();\r
+       }\r
+    }\r
+  else\r
+    {\r
+      fileloc_free (g_currentloc);\r
+      g_currentloc = fileloc_createBuiltin ();\r
+    }\r
+}\r
+\r
+static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/\r
+{\r
+  bool checkmacro = FALSE;\r
+  bool hasParams = FALSE;\r
+  bool noexpand = FALSE;\r
+  cstring sname;\r
+  char c;\r
+\r
+  cpp_setLocation (pfile);\r
+\r
+  DPRINTF (("Should check macro? %s", p));\r
+\r
+  if (expectiter || expectconstant || expectenditer)\r
+    {\r
+      if (expectiter)\r
+       {\r
+         expectiter = FALSE;\r
+         expectenditer = TRUE;\r
+       }\r
+      else\r
+       {\r
+         expectiter = FALSE;\r
+         expectconstant = FALSE;\r
+         expectenditer = FALSE;\r
+       }\r
+\r
+      if (notfunction || notparseable)\r
+       {\r
+         notfunction = FALSE;\r
+         notparseable = FALSE;\r
+         return FALSE;\r
+       }\r
+      else\r
+       {\r
+         return TRUE;\r
+       }\r
+    }\r
+\r
+  llassert (*p == '#');\r
+  p++;\r
+\r
+  while (*p == ' ' || *p == '\t')\r
+    {\r
+      p++;\r
+    }\r
+\r
+  llassert (*p == 'd'); /* define starts */\r
+\r
+  p += 6;\r
+\r
+  while (*p == ' ' || *p == '\t')\r
+    {\r
+      p++;\r
+    }\r
+\r
+  sname = cstring_fromChars (p);\r
+  DPRINTF (("Check macro: %s", sname));\r
+\r
+  while (((c = *p) != ' ')\r
+        && c != '\0' && c != '('\r
+        && c != '\t' && c != '\\' && c != '\n'\r
+        && !iscntrl (c))\r
+    {\r
+      p++;\r
+    }\r
+\r
+  hasParams = (c == '(');\r
+  *p = '\0';\r
+\r
+\r
+  if (notparseable)\r
+    {\r
+      notparseable = FALSE;\r
+    }\r
+  else if (notfunction || fileloc_isStandardLib (g_currentloc))\r
+    {\r
+      DPRINTF (("Clear notfunction"));\r
+      notfunction = FALSE;\r
+    }\r
+  else\r
+    {\r
+      if (noexpand)\r
+       {\r
+         checkmacro = TRUE;\r
+\r
+         if (!expectenditer)\r
+           {\r
+             noexpand = FALSE;\r
+           }\r
+       }\r
+      else\r
+       {\r
+         if (usymtab_existsReal (sname))\r
+           {\r
+             uentry ue = usymtab_lookup (sname);\r
+\r
+             DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));\r
+\r
+             if (fileloc_isPreproc (uentry_whereLast (ue)))\r
+               {\r
+                 goto macroDne;\r
+               }\r
+             else\r
+               {\r
+                 if (uentry_isSpecified (ue))\r
+                   {\r
+                     checkmacro = context_getFlag (FLG_SPECMACROS);\r
+                   }\r
+                 else\r
+                   {\r
+                     if (hasParams)\r
+                       {\r
+                         checkmacro = context_getFlag (FLG_LIBMACROS)\r
+                           || context_getFlag (FLG_FCNMACROS);\r
+                       }\r
+                   }\r
+               }\r
+           }\r
+         else\r
+           {\r
+           macroDne:\r
+             DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));\r
+\r
+             if (fileloc_isSystemFile (g_currentloc)\r
+                 && context_getFlag (FLG_SYSTEMDIREXPAND))\r
+               {\r
+                 ; /* don't check this macro */\r
+                 DPRINTF (("Don't check 1"));\r
+               }\r
+             else\r
+               {\r
+                 uentry le;\r
+                 \r
+                 if (hasParams)\r
+                   {\r
+                     DPRINTF (("Has params..."));\r
+\r
+                     if (context_getFlag (FLG_FCNMACROS))\r
+                       {\r
+                         if (usymtab_exists (sname))\r
+                           {\r
+                              /*\r
+                             ** only get here is macro is redefined\r
+                             ** error reported elsewhere\r
+                             */\r
+\r
+                             DPRINTF (("It exists!"));\r
+                           }\r
+                         else\r
+                           {\r
+                             /*\r
+                             ** We make it a forward function, since it might be declared elsewhere.\r
+                             ** After all headers have been processed, we should check the forward\r
+                             ** functions.\r
+                             */\r
+\r
+                             fileloc loc = fileloc_makePreproc (g_currentloc);\r
+\r
+                             /* the line is off-by-one, since the newline was already read */\r
+                             decLine ();\r
+\r
+                             if (expectfunction)\r
+                               {\r
+                                 expectfunction = FALSE;\r
+                               }\r
+\r
+                             le = uentry_makeForwardFunction (sname,\r
+                                                              typeId_invalid, loc);\r
+\r
+                             fileloc_free (loc);\r
+\r
+                             incLine ();\r
+\r
+                             /* Do not define here! */\r
+\r
+                             (void) usymtab_addEntry (le);\r
+                           }\r
+\r
+                         checkmacro = TRUE;\r
+                         DPRINTF (("Check: TRUE"));\r
+                       }\r
+                     else \r
+                       {\r
+                         DPRINTF (("Flag FCN_MACROS not set!"));\r
+                       }\r
+                   }\r
+                 else\r
+                   {\r
+                     DPRINTF (("No params"));\r
+\r
+                     if (context_getFlag (FLG_CONSTMACROS))\r
+                       {\r
+                         bool nocontent = FALSE;\r
+\r
+                         if (c == '\0')\r
+                           {\r
+                             nocontent = TRUE;\r
+                           }\r
+                         else\r
+                           {\r
+                             if (isspace (c))\r
+                               {\r
+                                 char *rest = p + 1;\r
+\r
+                                 /*\r
+                                 ** Check if there is nothing after the define.\r
+                                 */\r
+\r
+                                 while ((*rest) != '\0' && isspace (*rest))\r
+                                   {\r
+                                     rest++;\r
+                                   }\r
+\r
+                                 if (*rest == '\0')\r
+                                   {\r
+                                     nocontent = TRUE; /* empty macro, don't check */\r
+                                   }\r
+                               }\r
+                           }\r
+\r
+                         if (usymtab_exists (sname))\r
+                           {\r
+                             ;\r
+                           }\r
+                         else\r
+                           {\r
+                             fileloc loc = fileloc_makePreproc (g_currentloc);\r
+                             DPRINTF (("Make constant: %s", sname));\r
+                             le = uentry_makeConstant (sname,\r
+                                                       ctype_unknown, loc);\r
+                             (void) usymtab_addEntry (le);\r
+                           }\r
+\r
+                         checkmacro = !nocontent;\r
+                       }\r
+                   }\r
+               }\r
+\r
+             if (checkmacro && usymtab_existsType (sname))\r
+               {\r
+                 DPRINTF (("Making false..."));\r
+                 decLine ();\r
+                 ppllerror (message ("Specified type implemented as macro: %s", sname));\r
+                 checkmacro = FALSE;\r
+                 incLine ();\r
+               }\r
+           }\r
+       }\r
+    }\r
+\r
+  if (!checkmacro)\r
+    {\r
+      if (usymtab_exists (sname))\r
+       {\r
+         uentry ue = usymtab_lookupExpose (sname);\r
+         fileloc tloc = fileloc_makePreproc (g_currentloc);\r
+\r
+         uentry_setDefined (ue, tloc);\r
+         fileloc_free (tloc);\r
+         uentry_setUsed (ue, fileloc_undefined);\r
+       }\r
+      else\r
+       {\r
+         fileloc tloc = fileloc_makePreproc (g_currentloc);\r
+         uentry ue = uentry_makeExpandedMacro (sname, tloc);\r
+         DPRINTF (("Make expanded macro: %s", sname));\r
+         DPRINTF (("Not in symbol table: %s", sname));\r
+         \r
+         (void) usymtab_addGlobalEntry (ue);\r
+         fileloc_free (tloc);\r
+       }\r
+    }\r
+\r
+  *p = c;\r
+  DPRINTF (("Returning: %s", bool_unparse (checkmacro)));\r
+  return checkmacro;\r
+}\r
+\r
+static enum cpp_token\r
+cpp_handleComment (cppReader *pfile, struct parse_marker *smark)\r
+{\r
+  cppBuffer *pbuf = cppReader_getBuffer (pfile);\r
+  char *start;\r
+  int len;\r
+  bool eliminateComment = FALSE;\r
+\r
+  llassert (pbuf->buf != NULL);\r
+\r
+  start = pbuf->buf + smark->position;\r
+\r
+  llassert (pbuf->cur != NULL);\r
+  len = pbuf->cur - start;\r
+\r
+  if (start[0] == '*'\r
+      && start[1] == context_getCommentMarkerChar ())\r
+    {\r
+      int i;\r
+      char c = ' ';\r
+      char *scomment = start + 2;\r
+      char savec = start[len];\r
+\r
+      start[0] = BEFORE_COMMENT_MARKER[0];\r
+      start[1] = BEFORE_COMMENT_MARKER[1];\r
+\r
+      llassert (start[len - 2] == '*');\r
+      start[len - 2] = AFTER_COMMENT_MARKER[0];\r
+\r
+      llassert (start[len - 1] == '/');\r
+      start[len - 1] = AFTER_COMMENT_MARKER[1];\r
+\r
+      cppReader_reserve(pfile, size_fromInt (1 + len));\r
+      cppReader_putCharQ (pfile, c);\r
+\r
+      cpp_setLocation (pfile);\r
+\r
+      start[len] = '\0';\r
+\r
+      if (mstring_containsString (scomment, "/*"))\r
+       {\r
+         (void) cppoptgenerror \r
+           (FLG_NESTCOMMENT,\r
+            message ("Comment starts inside syntactic comment: %s", \r
+                     cstring_fromChars (scomment)),\r
+            pfile);\r
+       }\r
+\r
+      start[len] = savec;\r
+\r
+      if (mstring_equalPrefix (scomment, "ignore"))\r
+       {\r
+         if (!context_getFlag (FLG_NOCOMMENTS))\r
+           {\r
+             context_enterSuppressRegion ();\r
+           }\r
+       }\r
+      else if (mstring_equalPrefix (scomment, "end"))\r
+       {\r
+         if (!context_getFlag (FLG_NOCOMMENTS))\r
+           {\r
+             context_exitSuppressRegion ();\r
+           }\r
+       }\r
+      else if (mstring_equalPrefix (scomment, "notparseable"))\r
+       {\r
+         notparseable = TRUE;\r
+         expectmacro = TRUE;\r
+         eliminateComment = TRUE;\r
+       }\r
+      else if (mstring_equalPrefix (scomment, "notfunction"))\r
+       {\r
+         notfunction = TRUE;\r
+         expectmacro = TRUE;\r
+         eliminateComment = TRUE;\r
+       }\r
+      else if (mstring_equalPrefix (scomment, "iter"))\r
+       {\r
+         expectiter = TRUE;\r
+       }\r
+      else if (mstring_equalPrefix (scomment, "function"))\r
+       {\r
+         expectfunction = TRUE;\r
+       }\r
+      else if (mstring_equalPrefix (scomment, "constant"))\r
+       {\r
+         expectconstant = TRUE;\r
+       }\r
+      else\r
+       {\r
+         char sChar = *scomment;\r
+\r
+         if (sChar == '='\r
+             || sChar == '-'\r
+             || sChar == '+')\r
+           {\r
+             char *rest = scomment + 1;\r
+\r
+             if (mstring_equalPrefix (rest, "commentchar"))\r
+               {\r
+                 eliminateComment = TRUE;\r
+\r
+                 if (sChar == '=')\r
+                   {\r
+                     ppllerror (cstring_makeLiteral\r
+                                ("Cannot restore commentchar"));\r
+                   }\r
+                 else\r
+                   {\r
+                     char *next = scomment + 12; /* strlen commentchar = 12 */\r
+\r
+                     if (*next != ' ' && *next != '\t' && *next != '\n')\r
+                       {\r
+                         ppllerror\r
+                           (message\r
+                            ("Syntactic commentchar comment is not followed by a "\r
+                             "whitespace character: %c",\r
+                             *next));\r
+                       }\r
+                     else\r
+                       {\r
+                         char cchar = *(next + 1);\r
+\r
+                         if (cchar == '\0')\r
+                           {\r
+                             ppllerror\r
+                               (cstring_makeLiteral\r
+                                ("Cannot set commentchar to NUL"));\r
+                           }\r
+                         else\r
+                           {\r
+                             context_setCommentMarkerChar (cchar);\r
+                             /* setComment = TRUE; */\r
+                           }\r
+                       }\r
+                   }\r
+               }\r
+             else if (mstring_equalPrefix (scomment, "nestcomment"))\r
+               {\r
+                 /* fix from Mike Miller <MikeM@xata.com> */\r
+                 context_fileSetFlag (FLG_NESTCOMMENT,\r
+                                      ynm_fromCodeChar (sChar));\r
+               }\r
+             else if (mstring_equalPrefix (rest, "namechecks"))\r
+               {\r
+                 context_fileSetFlag (FLG_NAMECHECKS,\r
+                                      ynm_fromCodeChar (sChar));\r
+               }\r
+             else if (mstring_equalPrefix (rest, "macroredef"))\r
+               {\r
+                 context_fileSetFlag (FLG_MACROREDEF,\r
+                                      ynm_fromCodeChar (sChar));\r
+               }\r
+             else if (mstring_equalPrefix (rest, "usevarargs"))\r
+               {\r
+                 context_fileSetFlag (FLG_USEVARARGS,\r
+                                      ynm_fromCodeChar (sChar));\r
+               }\r
+             else if (mstring_equalPrefix (rest, "nextlinemacros"))\r
+               {\r
+                 context_fileSetFlag (FLG_MACRONEXTLINE,\r
+                                      ynm_fromCodeChar (sChar));\r
+               }\r
+             else if (mstring_equalPrefix (rest, "allmacros")\r
+                      || mstring_equalPrefix (rest, "fcnmacros")\r
+                      || mstring_equalPrefix (rest, "constmacros"))\r
+               {\r
+                 flagcode fl;\r
+\r
+                 if (mstring_equalPrefix (rest, "allmacros"))\r
+                   {\r
+                     fl = FLG_ALLMACROS;\r
+                   }\r
+                 else if (mstring_equalPrefix (rest, "fcnmacros"))\r
+                   {\r
+                     fl = FLG_FCNMACROS;\r
+                   }\r
+                 else\r
+                   {\r
+                     llassert (mstring_equalPrefix (rest, "constmacros"));\r
+                     fl = FLG_CONSTMACROS;\r
+                   }\r
+\r
+\r
+                 context_fileSetFlag (fl, ynm_fromCodeChar (sChar));\r
+                 notfunction = FALSE;\r
+               }\r
+             else\r
+               {\r
+                 ;\r
+               }\r
+           }\r
+         else\r
+           {\r
+             ;\r
+           }\r
+       }\r
+\r
+      if (eliminateComment)\r
+       {\r
+         goto removeComment;\r
+       }\r
+\r
+      /* Replaces comment char's in start with spaces */\r
+\r
+      for (i = 2; i < len - 2; i++)\r
+       {\r
+         if (start[i] == BEFORE_COMMENT_MARKER[0]\r
+             || start[i] == BEFORE_COMMENT_MARKER[1]\r
+             || start[i] == context_getCommentMarkerChar ())\r
+           {\r
+             start[i] = ' ';\r
+           }\r
+       }\r
+\r
+      cppReader_putStrN (pfile, start, size_fromInt (len));\r
+      parseClearMark (smark);\r
+      return CPP_COMMENT;\r
+    }\r
+  else\r
+    {\r
+    removeComment:\r
+      {\r
+       int i;\r
+\r
+       /*\r
+       ** Output the comment as all spaces so line/column\r
+       ** in output file is still correct.\r
+       */\r
+\r
+       char c = ' ';\r
+       cstring lintcomment = cstring_undefined;\r
+\r
+       if (context_getFlag (FLG_LINTCOMMENTS))\r
+         {\r
+           if (mstring_equalPrefix (start, "*NOTREACHED*/"))\r
+             {\r
+               lintcomment = cstring_makeLiteralTemp ("l_notreach");\r
+             }\r
+           else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))\r
+             {\r
+               lintcomment = cstring_makeLiteralTemp ("l_printfli");\r
+             }\r
+           else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))\r
+             {\r
+               lintcomment = cstring_makeLiteralTemp ("l_fallthrou");\r
+             }\r
+           else if (mstring_equalPrefix (start, "*ARGSUSED*/"))\r
+             {\r
+               lintcomment = cstring_makeLiteralTemp ("l_argsus");\r
+             }\r
+           else if (mstring_equalPrefix (start, "*FALLTHRU*/"))\r
+             {\r
+               lintcomment = cstring_makeLiteralTemp ("l_fallth");\r
+             }\r
+           else\r
+             {\r
+               lintcomment = cstring_undefined;\r
+             }\r
+         }\r
+       else\r
+         {\r
+           lintcomment = cstring_undefined;\r
+         }\r
+\r
+       if (cstring_isDefined (lintcomment))\r
+         {\r
+           c = BEFORE_COMMENT_MARKER[0];\r
+           start[0] = BEFORE_COMMENT_MARKER[1];\r
+\r
+           llassert (cstring_length (lintcomment) == len - 3);\r
+\r
+           for (i = 1; i < len - 2; i++)\r
+             {\r
+               start[i] = cstring_getChar (lintcomment, i);\r
+             }\r
+           \r
+           start[len - 2] = AFTER_COMMENT_MARKER[0];\r
+           start[len - 1] = AFTER_COMMENT_MARKER[1];\r
+         }\r
+       else\r
+         {\r
+           /* Replaces  char's in start with spaces */\r
+           for (i = 0; i < len; i++)\r
+             {\r
+               if (start[i] == '/'\r
+                   && i < len - 1\r
+                   && start[i + 1] == '*') {\r
+                 (void) cppoptgenerror (FLG_NESTCOMMENT,\r
+                                        message ("Comment starts inside comment"),\r
+                                        pfile);\r
+               }\r
+               \r
+               if (start[i] != '\n')\r
+                 {\r
+                   start[i] = ' ';\r
+                 }\r
+             }\r
+         }\r
+\r
+       cppReader_reserve (pfile, size_fromInt (1 + len));\r
+       cppReader_putCharQ (pfile, c);\r
+       cppReader_putStrN (pfile, start, size_fromInt (len));\r
+       parseClearMark (smark);\r
+       return CPP_COMMENT;\r
+      }\r
+    }\r
+}\r
+\r
+static int cpp_openIncludeFile (char *filename)\r
+{\r
+  int res = open (filename, O_RDONLY, 0666);\r
+\r
+  /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */\r
+  if (res >= 0)\r
+    {\r
+      if (!fileTable_exists (context_fileTable (),\r
+                            cstring_fromChars (filename)))\r
+       {\r
+         (void) fileTable_addHeaderFile (context_fileTable (),\r
+                                         cstring_fromChars (filename));\r
+       }\r
+      else\r
+       {\r
+         DPRINTF (("File already exists: %s", filename));\r
+       }\r
+    }\r
+\r
+  return res;\r
+}\r
+\r
+static bool cpp_skipIncludeFile (cstring fname)\r
+{\r
+  if (context_isSystemDir (fname))\r
+    {\r
+      DPRINTF (("System dir: %s", fname));\r
+\r
+      if (lcllib_isSkipHeader (fname))\r
+       {\r
+         DPRINTF (("Skip include TRUE: %s", fname));\r
+         return TRUE;\r
+       }\r
+      \r
+      if (context_getFlag (FLG_SKIPSYSHEADERS))\r
+       {\r
+         DPRINTF (("Skip include TRUE: %s", fname));\r
+         return TRUE;\r
+       }\r
+    }\r
+\r
+  if (context_getFlag (FLG_SINGLEINCLUDE))\r
+    {\r
+      fname = removePreDirs (fname);\r
+\r
+# if defined (WIN32) || defined (OS2)\r
+      cstring_replaceAll (fname, '\\', '/');\r
+# endif\r
+\r
+      if (fileTable_exists (context_fileTable (), fname))\r
+       {\r
+         DPRINTF (("Skip include TRUE: %s", fname));\r
+         return TRUE;\r
+       }\r
+    }\r
+\r
+  DPRINTF (("Skip include FALSE: %s", fname));\r
+  return FALSE;\r
+}\r
+\r
+static int cpp_peekN (cppReader *pfile, int n)\r
+{\r
+  cppBuffer *buf = cppReader_getBuffer (pfile);\r
+\r
+  llassert (buf->cur != NULL);\r
+\r
+  return (buf->rlimit - buf->cur >= (n)\r
+         ? buf->cur[n]\r
+         : EOF);\r
+}\r
+\r
+cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)\r
+{\r
+  return buf + 1;\r
+}\r
+\r
+void cppBuffer_forward (cppBuffer *buf, int n)\r
+{\r
+  llassert (buf->cur != NULL);\r
+  buf->cur += n;\r
+}\r
index 272181e40fc4ab3de8e5d6e1ae95fb790087a0d3..aa9887776f3bb98bccfb791791ed106c8a424d4d 100644 (file)
-/*;-*-C-*-; 
-** Copyright (c) Massachusetts Institute of Technology 1994-1998.
-**          All Rights Reserved.
-**          Unpublished rights reserved under the copyright laws of
-**          the United States.
-**
-** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-** OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
-**
-** This code is distributed freely and may be used freely under the 
-** following conditions:
-**
-**     1. This notice may not be removed or altered.
-**
-**     2. Works derived from this code are not distributed for
-**        commercial gain without explicit permission from MIT 
-**        (for permission contact lclint-request@sds.lcs.mit.edu).
-*/
-/*
- * Modified by Herbert 08/19/97:
- * - added #include for IBM's OS/2 compiler.
- * - fixed weird bug with lookup of tmp files (OS/2 and MSDOS only).
- */
-
-/*
- * Modified by Mike Smith 
- * Corrected missing 'line' in scanf() calls in handleSpecial().
- * Without this, I get an error when LCLint hits a '#line' directive
- * in the pre-pre-processed source files. For safety, I have made these
- * conditional on OS2 and MSDOS because I don't understand why noone else
- * has seen this problem.
- *
- * Modified by Mike Smith, 4th June 1997
- * Finally resolved the #line problem.  The scanf() calls have been fixed to
- * allow the following #line forms:-
- *
- *        #line 123 "filename"
- *        #line 123
- *        # 123 "filename"
- *        # 123
- *
- * The last two are generated by the GNU pre-processor, apparently
- */
-
-Digit                  [0-9]
-Letter                 [a-zA-Z_$]
-H                      [a-fA-F0-9]
-E                      [Ee][+-]?{Digit}+
-U                       (u|U)
-L                       (l|L)
-FS                     (f|F|l|L)
-IS                     (u|U|l|L)*
-ULSuffix                ({U}{L}|{L}{U})
-
-%{
-/*
-** based on original C lexer by Nate Osgood
-**    from hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993
-**
-*/
-
-# include "lclintMacros.nf"
-# include <unistd.h>
-# include "basic.h"
-
-# include "cgrammar.h"
-# include "cgrammar_tokens.h"
-
-# include "fileIdList.h"
-# include "portab.h"
-
-# if defined(OS2) && defined(__IBMC__)
-   /* needed for isatty()... */
-# include <io.h>
-# endif
-
-static bool lastWasString = FALSE;
-static char savechar = '\0';
-
-/*@notfunction@*/
-# define yyinput() (incColumn (), getc (yyin))
-
-static /*@owned@*/ cstring lastidprocessed = cstring_undefined;
-static int lminput (void);
-static int tokLength = 0;
-static bool inSpecPart = FALSE;
-static bool continueLine = FALSE;
-
-static int ninput (void);
-static char processChar (void);
-static double processFloat (void);
-static /*@only@*/ exprNode processString (void);
-static long processDec (void);
-static long processHex (void);
-static long processOctal (void);
-static int processIdentifier (/*@only@*/ cstring)
-   /*@globals undef lastidprocessed@*/ ;
-static bool processHashIdentifier (/*@only@*/ cstring)
-   /*@globals undef lastidprocessed@*/ ;
-
-static int processSpec (int);
-static bool handleSpecial (char *);
-static int handleLlSpecial (void);
-static void handleMacro (void);
-static bool processMacro (void);
-static /*@only@*/ cstring makeIdentifier (char *);
-
-/* yes, this is exported! */
-bool g_expectingTypeName = TRUE; /* beginning of file can be type name! */
-
-static bool expectingMetaStateName = FALSE;
-
-static int returnInt (ctype, long);
-static int returnFloat (ctype, double);
-static int returnChar (char);
-static void setTokLength (int) /*@modifies g_currentloc@*/ ;
-static void setTokLengthT (size_t) /*@modifies g_currentloc@*/ ;
-
-static void advanceLine (void)
-{
-  tokLength = 0;
-  beginLine ();
-}
-    
-/*@-allmacros@*/
-# define RETURN_INT(c,i) \
-  do { lastWasString = FALSE; \
-       return (returnInt (c, i)); } while (FALSE)
-
-# define RETURN_FLOAT(c,f) \
-  do { lastWasString = FALSE; \
-       return (returnFloat (c, f)); \
-       } while (FALSE)
-
-# define RETURN_CHAR(c) \
-  do { lastWasString = FALSE; \
-       return (returnChar (c)); \
-     } while (FALSE)
-
-# define RETURN_TOK(t) \
-  do { yylval.tok = lltok_create (t, fileloc_decColumn (g_currentloc, tokLength)); \
-       tokLength = 0; \
-       lastWasString = FALSE; \
-       return (t); } while (FALSE)
-
-# define RETURN_TYPE(t, ct) \
-  do { yylval.ctyp = ct; tokLength = 0; return (t); } while (FALSE)
-
-/* don't fileloc_decColumn (g_currentloc, tokLength));  
-   the string could have \n's in it!
-*/
-
-# define RETURN_STRING(c) \
- do { yylval.expr = exprNode_stringLiteral (c, fileloc_decColumn (g_currentloc, tokLength)); \
-      tokLength = 0; \
-      lastWasString = TRUE; \
-      return (CCONSTANT); } while (FALSE)
-
-# define RETURN_EXPR(e) \
- do { yylval.expr = e; \
-      tokLength = 0; \
-      lastWasString = TRUE; \
-      return (CCONSTANT); } while (FALSE)
-
-/*@=allmacros@*/
-
-static void setTokLength (int len) 
-{
-  addColumn (len);
-  tokLength = len;
-  DPRINTF (("Set tok length: %d", len));
-}
-
-static void setTokLengthT (size_t len)
-{
-  setTokLength (size_toInt (len));
-}
-
-# include "flex.head"
-
-/*@-unrecog@*/ /*@i5343@*/
-
-%}
-
-%%
-
-"/*"           { llfatalbug (cstring_makeLiteral ("Comment in pre-processor output")); }
-
-"#"{Letter}({Letter}|{Digit})*  { 
-                 context_saveLocation (); 
-                 setTokLength (longUnsigned_toInt (mstring_length (yytext))); 
-
-                 if (processHashIdentifier (makeIdentifier (yytext + 1)))
-                   {
-                    if (lastWasString)
-                      {
-                        /* was nothing! */ /*@i32@*/
-                        RETURN_STRING (cstring_makeLiteral ("\"\""));
-                      }
-                    else
-                      {
-                        RETURN_STRING (cstring_makeLiteral ("\"\""));
-                      }
-                  }
-                 else
-                   { 
-                    if (handleSpecial (yytext)) 
-                       { 
-                        setTokLength (1); 
-                        RETURN_TOK (0); 
-                      }
-                  }
-                } 
-"#"             { if (handleSpecial (yytext)) 
-                    { 
-                       setTokLength (1); RETURN_TOK (0); 
-                     }
-                }
-"..."           { setTokLength (3); RETURN_TOK (CTOK_ELIPSIS); }
-"break"                { setTokLength (5); RETURN_TOK (BREAK); }
-"case"         { setTokLength (4); RETURN_TOK (CASE); }
-"continue"     { setTokLength (8); RETURN_TOK (CONTINUE); }
-"default"      { setTokLength (7); RETURN_TOK (DEFAULT); }
-"do"           { setTokLength (2); RETURN_TOK (DO); }
-"else"         { setTokLength (4); RETURN_TOK (CELSE); }
-"for"          { setTokLength (3); RETURN_TOK (CFOR); }
-"goto"         { setTokLength (4); RETURN_TOK (GOTO); }
-"if"           { setTokLength (2); RETURN_TOK (CIF); }
-"return"       { setTokLength (6); RETURN_TOK (RETURN); }
-"sizeof"       { setTokLength (6); RETURN_TOK (CSIZEOF); }
-"offsetof"     { setTokLength (8); RETURN_TOK (COFFSETOF); }
-"switch"       { setTokLength (6); RETURN_TOK (SWITCH); }
-"while"                { setTokLength (5); RETURN_TOK (WHILE); }
-"va_arg"        { setTokLength (6); RETURN_TOK (VA_ARG); }   
-"va_dcl"        { setTokLength (6); RETURN_TOK (VA_DCL); }   
-"inline"        { 
-                  /* gcc extension...this might not be appropriate */
-                  setTokLength (6); RETURN_TOK (QINLINE); }
-
-"struct"        { setTokLength (6); RETURN_TOK (CSTRUCT); }  
-"typedef"       { setTokLength (7); RETURN_TOK (CTYPEDEF); }
-
-"union"         { setTokLength (5); RETURN_TOK (CUNION); }
-"enum"          { setTokLength (4); RETURN_TOK (CENUM); }
-
-"void"         { setTokLength (4); RETURN_TYPE (CVOID, ctype_void); }
-"int"          { setTokLength (3); RETURN_TYPE (CINT, ctype_int); }
-"double"       { setTokLength (6); RETURN_TYPE (CDOUBLE, ctype_double); }
-"char"         { setTokLength (4); RETURN_TYPE (CGCHAR, ctype_char); }
-"float"                { setTokLength (5); RETURN_TYPE (CGFLOAT, ctype_float); }
-
-"long"         { setTokLength (4); RETURN_TOK (QLONG); }
-"short"                { setTokLength (5); RETURN_TOK (QSHORT); }
-"unsigned"     { setTokLength (8); RETURN_TOK (QUNSIGNED); }
-"signed"       { setTokLength (6); RETURN_TOK (QSIGNED); }
-
-"volatile"     { setTokLength (8); RETURN_TOK (QVOLATILE); }
-"const"                { setTokLength (5); RETURN_TOK (QCONST); }
-
-                        /* some systems expect this! [gack!] */ 
-"__const"      { setTokLength (7); RETURN_TOK (QCONST); }
-
-"extern"       { setTokLength (6); RETURN_TOK (QEXTERN); }
-"auto"         { setTokLength (4); RETURN_TOK (QAUTO); }
-"register"     { setTokLength (8); RETURN_TOK (QREGISTER); }
-"static"       { setTokLength (6); RETURN_TOK (QSTATIC); }
-
-\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }
-L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }
-"out"                   { return (processSpec (QOUT)); }
-"in"                    { return (processSpec (QIN)); }
-"partial"               { return (processSpec (QPARTIAL)); }
-"special"               { return (processSpec (QSPECIAL)); }
-"anytype"               { return (processSpec (QANYTYPE)); }
-"integraltype"          { return (processSpec (QINTEGRALTYPE)); }
-"unsignedintegraltype"  { return (processSpec (QUNSIGNEDINTEGRALTYPE)); }
-"signedintegraltype"    { return (processSpec (QSIGNEDINTEGRALTYPE)); }
-"keep"                  { return (processSpec (QKEEP)); }
-"null"                  { return (processSpec (QNULL)); } 
-"notnull"               { return (processSpec (QNOTNULL)); } 
-"isnull"                { return (processSpec (QISNULL)); } 
-"truenull"              { return (processSpec (QTRUENULL)); } 
-"falsenull"             { return (processSpec (QFALSENULL)); } 
-"relnull"               { return (processSpec (QRELNULL)); }
-"reldef"                { return (processSpec (QRELDEF)); }
-"exposed"               { return (processSpec (QEXPOSED)); }
-"newref"                { return (processSpec (QNEWREF)); }
-"tempref"               { return (processSpec (QTEMPREF)); }
-"killref"               { return (processSpec (QKILLREF)); }
-"refcounted"            { return (processSpec (QREFCOUNTED)); }
-"checked"               { return (processSpec (QCHECKED)); }
-"checkmod"              { return (processSpec (QCHECKMOD)); }
-"checkedstrict"         { return (processSpec (QCHECKEDSTRICT)); }
-"unchecked"             { return (processSpec (QUNCHECKED)); }
-"only"                  { return (processSpec (QONLY)); }
-"owned"                 { return (processSpec (QOWNED)); }
-"observer"              { return (processSpec (QOBSERVER)); }
-"dependent"             { return (processSpec (QDEPENDENT)); }
-"unused"                { return (processSpec (QUNUSED)); }
-"external"              { return (processSpec (QEXTERNAL)); }
-"sef"                   { return (processSpec (QSEF)); }
-"shared"                { return (processSpec (QSHARED)); }
-"yield"                 { return (processSpec (QYIELD)); }
-"undef"                 { return (processSpec (QUNDEF)); }
-"killed"                { return (processSpec (QKILLED)); }
-"nullterminated"        { return (processSpec (QNULLTERMINATED));}
-"MaxSet"                { return (processSpec (QMAXSET));}
-"MaxRead"               { return (processSpec (QMAXREAD));}
-"maxSet"                { return (processSpec (QMAXSET));}
-"maxRead"               { return (processSpec (QMAXREAD));}
-
-{Letter}({Letter}|{Digit})* { int tok; 
-                             context_saveLocation (); 
-                             setTokLength (longUnsigned_toInt (mstring_length (yytext))); 
-                             tok = processIdentifier (makeIdentifier (yytext)); 
-                             if (tok != BADTOK)
-                               {
-                                 return (tok);
-                               }
-                           }
-0[xX]{H}+              { setTokLengthT (mstring_length (yytext)); 
-                          RETURN_INT (ctype_int, processHex ());  /* evs 2000-05-17 was ctype_uint */
-                       }
-0[xX]{H}+{L}           { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_lint, processHex ()); }
-0[xX]{H}+{L}{L}                { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_llint, processHex ()); }
-0[xX]{H}+{U}           { setTokLengthT (mstring_length (yytext)); 
-                          RETURN_INT (ctype_uint, processHex ()); }
-0[xX]{H}+{ULSuffix}     { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_ulint, processHex ()); }
-0[xX]{H}+{U}{L}{L}      { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_ullint, processHex ()); }
-0[xX]{H}+{L}{L}{U}      { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_ullint, processHex ()); }
-0{Digit}+              { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_int, processOctal ()); } 
-0{Digit}+{U}           { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_uint, processOctal ()); } 
-0{Digit}+{L}           { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_lint, processOctal ()); } 
-0{Digit}+{L}{L}                { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_llint, processOctal ()); } 
-0{Digit}+{ULSuffix}     { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_ulint, processOctal ()); } 
-0{Digit}+{U}{L}{L}      { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_ullint, processOctal ()); } 
-0{Digit}+{L}{L}{U}      { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_INT (ctype_ullint, processOctal ()); } 
-{Digit}+              { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_INT (ctype_int, processDec ()); } 
-{Digit}+{U}           { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_INT (ctype_uint, processDec ()); } 
-{Digit}+{L}           { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_INT (ctype_lint, processDec ()); } 
-{Digit}+{L}{L}        { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_INT (ctype_llint, processDec ()); } 
-{Digit}+{ULSuffix}     { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_INT (ctype_ulint, processDec ()); } 
-{Digit}+{U}{L}{L}      { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_INT (ctype_ullint, processDec ()); } 
-{Digit}+{L}{L}{U}      { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_INT (ctype_ullint, processDec ()); } 
-'(\\.|[^\\'])+'               { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_CHAR (processChar ()); }
-L'(\\.|[^\\'])+'       { setTokLengthT (mstring_length (yytext)); 
-                         RETURN_CHAR (processChar ()); }
-{Digit}+{E}[fF]        { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_FLOAT (ctype_float, processFloat ()); }
-{Digit}+{E}[lL]        { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_FLOAT (ctype_ldouble, processFloat ()); }
-{Digit}+{E}            { setTokLengthT (mstring_length (yytext)); 
-                        RETURN_FLOAT (ctype_double, processFloat ()); }
-
-{Digit}*"."{Digit}+({E})?[fF] { setTokLengthT (mstring_length (yytext)); 
-                               RETURN_FLOAT (ctype_float, processFloat ()); }
-{Digit}*"."{Digit}+({E})?[lL] { setTokLengthT (mstring_length (yytext)); 
-                               RETURN_FLOAT (ctype_ldouble, processFloat ()); }
-{Digit}*"."{Digit}+({E})?     { setTokLengthT (mstring_length (yytext)); 
-                               RETURN_FLOAT (ctype_double, processFloat ()); }
-
-{Digit}+"."{Digit}*({E})?[fF]   { setTokLengthT (mstring_length (yytext)); 
-                                 RETURN_FLOAT (ctype_float, processFloat ()); }
-{Digit}+"."{Digit}*({E})?[lL]   { setTokLengthT (mstring_length (yytext)); 
-                                 RETURN_FLOAT (ctype_ldouble, processFloat ()); }
-{Digit}+"."{Digit}*({E})?       { setTokLengthT (mstring_length (yytext)); 
-                                 RETURN_FLOAT (ctype_double, processFloat ()); }
-
-">>="          { setTokLength (3); RETURN_TOK (RIGHT_ASSIGN); }
-"<<="          { setTokLength (3); RETURN_TOK (LEFT_ASSIGN); }
-"+="           { setTokLength (2); RETURN_TOK (ADD_ASSIGN); }
-"-="           { setTokLength (2); RETURN_TOK (SUB_ASSIGN); }
-"*="           { setTokLength (2); RETURN_TOK (MUL_ASSIGN); }
-"/="           { setTokLength (2); RETURN_TOK (DIV_ASSIGN); }
-"%="           { setTokLength (2); RETURN_TOK (MOD_ASSIGN); }
-"&="           { setTokLength (2); RETURN_TOK (AND_ASSIGN); }
-"^="           { setTokLength (2); RETURN_TOK (XOR_ASSIGN); }
-"|="           { setTokLength (2); RETURN_TOK (OR_ASSIGN); }
-">>"           { setTokLength (2); RETURN_TOK (RIGHT_OP); }
-"<<"           { setTokLength (2); RETURN_TOK (LEFT_OP); }
-"++"           { setTokLength (2); RETURN_TOK (INC_OP); }
-"--"           { setTokLength (2); RETURN_TOK (DEC_OP); }
-"->"           { setTokLength (2); RETURN_TOK (ARROW_OP); }
-"&&"           { setTokLength (2); RETURN_TOK (AND_OP); }
-"||"           { setTokLength (2); RETURN_TOK (OR_OP); }
-"<="           { setTokLength (2); RETURN_TOK (LE_OP); }
-">="           { setTokLength (2); RETURN_TOK (GE_OP); }
-"=="           { setTokLength (2); RETURN_TOK (EQ_OP); }
-"!="           { setTokLength (2); RETURN_TOK (NE_OP); }
-";"            { setTokLength (1); RETURN_TOK (TSEMI); }
-"{"            { setTokLength (1); RETURN_TOK (TLBRACE); }
-"}"            { setTokLength (1); RETURN_TOK (TRBRACE); }
-","            { setTokLength (1); RETURN_TOK (TCOMMA); }
-":"            { setTokLength (1); RETURN_TOK (TCOLON); }
-"="            { setTokLength (1); RETURN_TOK (TASSIGN); }
-"("            { setTokLength (1); RETURN_TOK (TLPAREN); }
-")"            { setTokLength (1); RETURN_TOK (TRPAREN); }
-"["            { setTokLength (1); RETURN_TOK (TLSQBR); }
-"]"            { setTokLength (1); RETURN_TOK (TRSQBR); }
-"."            { setTokLength (1); RETURN_TOK (TDOT); }
-"&"            { setTokLength (1); RETURN_TOK (TAMPERSAND); }
-"!"            { setTokLength (1); RETURN_TOK (TEXCL); }
-
-
-"~"            { setTokLength (1); RETURN_TOK (TTILDE); }
-"-"            { setTokLength (1); RETURN_TOK (TMINUS); }
-"+"            { setTokLength (1); RETURN_TOK (TPLUS); }
-"*"            { setTokLength (1); RETURN_TOK (TMULT); }
-"/"            { setTokLength (1); RETURN_TOK (TDIV); }
-"%"            { setTokLength (1); RETURN_TOK (TPERCENT); }
-"<"            { setTokLength (1); RETURN_TOK (TLT); }
-">"            { setTokLength (1); RETURN_TOK (TGT); }
-"^"            { setTokLength (1); RETURN_TOK (TCIRC); }
-"|"            { setTokLength (1); RETURN_TOK (TBAR); }
-"?"            { setTokLength (1); RETURN_TOK (TQUEST); }
-
-
-"/\\"          { setTokLength (1); RETURN_TOK (TCAND); }
-
-
-[ \t\v\f]      { incColumn (); }
-\n              { context_incLineno ();
-                  if (tokLength != 0) { 
-                   tokLength = 0; 
-                   /* No error to report 
-                   voptgenerror
-                     (FLG_SYNTAX, 
-                      message ("Likely parse error: token spans multiple lines."),
-                      g_currentloc);
-                   */
-                 }
-                 
-                 if (continueLine)
-                   {
-                     continueLine = FALSE;
-                   }
-                 else 
-                  {
-                    if (context_inMacro ())
-                      {
-                        /* Don't use RETURN_TOK */
-                        yylval.tok = lltok_create (TENDMACRO, g_currentloc);
-                        lastWasString = FALSE;
-                        return (TENDMACRO);
-                      }  
-                  }
-               }
-"@@MR@@"        { setTokLength (6); 
-                 
-                 if (processMacro ()) {
-                   if (context_inIterDef ()) 
-                     { 
-                       RETURN_TOK (LLMACROITER); 
-                     }
-                   if (context_inIterEnd ())
-                     {
-                       RETURN_TOK (LLMACROEND); 
-                     }
-                   if (context_inMacro ())
-                     {
-                       RETURN_TOK (LLMACRO); 
-                     }
-                 }
-               }
-"@QLMR"         { if (context_inHeader () || context_inFunction ())
-                   { 
-                     handleMacro ();
-                   }
-                  else
-                   {
-                     int nspchar = ninput ();
-                     int nspaces;
-
-                     /* 
-                     ** This is a hack to get the column number correct.
-                     */
-
-                     llassert (nspchar >= '0' && nspchar <= '9');
-                     
-                     nspaces = nspchar - '0';
-
-                     setTokLength (5 + nspaces); 
-                     
-                     if (processMacro ()) 
-                       {
-                         if (context_inIterDef ()) 
-                           {
-                             RETURN_TOK (LLMACROITER); 
-                           }
-                         if (context_inIterEnd ())
-                           {
-                             RETURN_TOK (LLMACROEND); 
-                           }
-                         if (context_inMacro ())
-                           { 
-                             RETURN_TOK (LLMACRO); 
-                           }
-                       }
-                   }
-               }
-"@.CT"          { setTokLength (4); lldiagmsg (ctype_unparseTable ()); }
-"@.FA"          { setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); }
-"@.F"           { setTokLength (3); 
-                 lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc)));
-               }
-"@.L"           { setTokLength (3); usymtab_printLocal (); }
-"@.A"           { setTokLength (3); lldiagmsg (usymtab_unparseAliases ()); }
-"@.C"           { setTokLength (3); lldiagmsg (context_unparse ()); }
-"@.W"           { setTokLength (3); lldiagmsg (context_unparseClauses ()); }
-"@.G"           { setTokLength (3); usymtab_printGuards (); }
-"@.S"           { setTokLength (3); usymtab_printOut (); }
-"@.X"           { setTokLength (3); usymtab_printAll (); }
-"@.Z"           { setTokLength (3); usymtab_printComplete (); }
-"@.T"           { setTokLength (3); usymtab_printTypes (); }
-"@.K"           { setTokLength (3); lldiagmsg (usymtab_unparseStack ()); }
-"@.M"           { setTokLength (3); 
-                 lldiagmsg (message ("Can modify: %q", 
-                                 sRefSet_unparse (context_modList ()))); 
-               }
-"%{"            { /* BEFORE_COMMENT_MARKER */
-                  int tok; 
-                 incColumn (); incColumn ();
-                 tok = handleLlSpecial (); 
-
-                 if (tok != BADTOK)
-                   {
-                     if (tok == CANNOTATION) {
-                       return (tok);
-                     } else {
-                       /* Beware - this bashes yylval! */
-                       RETURN_TOK (tok); 
-                     }
-                   }
-               }
-"%}"            { /* AFTER_COMMENT_MARKER */ 
-                  setTokLength (2);
-                 inSpecPart = FALSE;
-                 RETURN_TOK (QENDMACRO); }
-"\\"            { incColumn (); continueLine = TRUE; }
-.              { incColumn (); 
-                  if ((int) *yytext == 13 ) {
-                    ;
-                  } else {
-                   voptgenerror
-                     (FLG_SYNTAX, 
-                      message ("Invalid character (ascii: %d), skipping character",
-                               (int)(*yytext)),
-                      g_currentloc);
-                 }
-               }
-%%
-
-struct skeyword
-{
-  /*@null@*/ /*@observer@*/ char *name;
-  int token;
-} ;
-
-/*
-** These tokens are followed by syntax that is parsed by the 
-** grammar proper.
-*/
-
-struct skeyword s_parsetable[] = {
-  { "modifies", QMODIFIES } ,
-  { "globals", QGLOBALS } ,
-  { "alt", QALT } ,
-  { "warn", QWARN } ,
-  { "constant", QCONSTANT } ,
-  { "function", QFUNCTION } ,
-  { "iter", QITER } ,
-  { "defines", QDEFINES } ,
-  { "uses", QUSES } ,
-  { "allocates", QALLOCATES } ,
-  { "sets", QSETS } ,
-  { "releases", QRELEASES } ,
-  { "pre", QPRECLAUSE } ,
-  { "post", QPOSTCLAUSE } ,
-  { "setBufferSize", QSETBUFFERSIZE},
-  { "setStringLength", QSETSTRINGLENGTH},
-  { "testinRange", QTESTINRANGE},
-  { "requires", QPRECLAUSE } ,
-  { "ensures", QPOSTCLAUSE } ,
-  { NULL, BADTOK } 
-} ;
-
-/*
-** These tokens are either stand-alone tokens, or followed by 
-** token-specific text.
-*/
-
-struct skeyword s_keytable[] = {
-  { "anytype", QANYTYPE } ,
-  { "integraltype", QINTEGRALTYPE } ,
-  { "unsignedintegraltype", QUNSIGNEDINTEGRALTYPE } ,
-  { "signedintegraltype", QSIGNEDINTEGRALTYPE } ,
-  { "out", QOUT } ,
-  { "in", QIN } ,
-  { "only", QONLY } , 
-  { "owned", QOWNED } ,
-  { "dependent", QDEPENDENT } ,
-  { "partial", QPARTIAL } ,
-  { "special", QSPECIAL } ,
-  { "truenull", QTRUENULL } ,
-  { "falsenull", QFALSENULL } ,
-  { "keep", QKEEP } ,
-  { "kept", QKEPT } ,
-  { "notnull", QNOTNULL } ,
-  { "abstract", QABSTRACT } ,
-  { "concrete", QCONCRETE } ,
-  { "mutable", QMUTABLE } ,
-  { "immutable", QIMMUTABLE } ,
-  { "unused", QUNUSED } ,
-  { "external", QEXTERNAL } ,
-  { "sef", QSEF } ,
-  { "unique", QUNIQUE } ,
-  { "returned", QRETURNED } ,
-  { "exposed", QEXPOSED } ,
-  { "refcounted", QREFCOUNTED } ,
-  { "refs", QREFS } ,
-  { "newref", QNEWREF } ,
-  { "tempref", QTEMPREF } ,
-  { "killref", QKILLREF } ,
-  { "null", QNULL } ,
-  { "relnull", QRELNULL } ,
-  { "nullterminated", QNULLTERMINATED }, 
-  { "setBufferSize", QSETBUFFERSIZE },
-  { "testInRange", QTESTINRANGE},
-  { "MaxSet", QMAXSET},
-  { "MaxRead", QMAXREAD},
-  { "reldef", QRELDEF } ,
-  { "observer", QOBSERVER } ,
-  { "exits", QEXITS } ,
-  { "mayexit", QMAYEXIT } ,
-  { "trueexit", QTRUEEXIT } ,
-  { "falseexit", QFALSEEXIT } ,
-  { "neverexit", QNEVEREXIT } ,
-  { "temp", QTEMP } ,
-  { "shared", QSHARED } ,
-  { "ref", QREF } ,
-  { "unchecked", QUNCHECKED } ,
-  { "checked", QCHECKED } ,
-  { "checkmod", QCHECKMOD } ,
-  { "checkedstrict", QCHECKEDSTRICT } ,
-  { "innercontinue", QINNERCONTINUE } ,
-  { "innerbreak", QINNERBREAK } ,
-  { "loopbreak", QLOOPBREAK } ,
-  { "switchbreak", QSWITCHBREAK } ,
-  { "safebreak", QSAFEBREAK } , 
-  { "fallthrough", QFALLTHROUGH } ,
-  { "l_fallthrou", QLINTFALLTHROUGH } , 
-  { "l_fallth", QLINTFALLTHRU } ,
-  { "notreached", QNOTREACHED } ,
-  { "l_notreach", QLINTNOTREACHED } ,
-  { "printflike", QPRINTFLIKE } ,
-  { "l_printfli", QLINTPRINTFLIKE } ,
-  { "scanflike", QSCANFLIKE } ,
-  { "messagelike", QMESSAGELIKE } ,
-  { "l_argsus", QARGSUSED } ,
-  { NULL, BADTOK } 
-} ;
-
-/*
-** would be better if these weren't hard coded...
-*/
-
-static bool isArtificial (cstring s)
-{
-  return (cstring_equalLit (s, "modifies") 
-         || cstring_equalLit (s, "globals") 
-         || cstring_equalLit (s, "warn")
-         || cstring_equalLit (s, "alt"));
-}
-
-void swallowMacro (void)
-{
-  int i;
-  bool skipnext = FALSE;
-
-  while ((i = lminput ()) != EOF)
-    {
-      char c = (char) i;
-      
-      
-      if (c == '\\')
-       {
-         skipnext = TRUE;
-       }
-      else if (c == '\n')
-       {
-         if (skipnext)
-           {
-             skipnext = FALSE;
-           }
-         else
-           {
-             reader_checkUngetc (i, yyin);
-             return;
-           }
-       }
-    }
-
-  if (i != EOF)
-    {
-      reader_checkUngetc (i, yyin);
-    }
-}
-
-static int commentMarkerToken (cstring s)
-{
-  int i = 0;
-  
-  while (s_parsetable[i].name != NULL) 
-    {
-      DPRINTF (("Try :%s:%s:", s, s_parsetable[i].name));
-
-      if (cstring_equalLit (s, s_parsetable[i].name))
-       {
-         return s_parsetable[i].token;
-       }
-
-      i++;
-    }
-
-  return BADTOK;
-}
-
-static int tokenMacroCode (cstring s)
-{
-  int i = 0;
-  
-  while (s_keytable[i].name != NULL) 
-    {
-      if (cstring_equalLit (s, s_keytable[i].name)) 
-       {
-         if (s_keytable[i].token == QLINTFALLTHROUGH) 
-           {
-             voptgenerror
-               (FLG_WARNLINTCOMMENTS,
-                cstring_makeLiteral
-                ("Traditional lint comment /*FALLTHROUGH*/ used.  "
-                 "This is interpreted by "
-                 "LCLint in the same way as most Unix lints, but it is "
-                 "preferable to replace it with the /*@fallthrough@*/ "
-                 "semantic comment"),
-                g_currentloc);
-             return QFALLTHROUGH;            
-           }
-         else if (s_keytable[i].token == QLINTFALLTHRU)
-           {
-             voptgenerror 
-               (FLG_WARNLINTCOMMENTS,
-                cstring_makeLiteral
-                ("Traditional lint comment /*FALLTHRU*/ used.  "
-                 "This is interpreted by "
-                 "LCLint in the same way as most Unix lints, but it is "
-                 "preferable to replace it with the /*@fallthrough@*/ "
-                 "semantic comment"),
-                g_currentloc);
-             return QFALLTHROUGH;
-           }
-         else if (s_keytable[i].token == QLINTNOTREACHED)
-           {
-             voptgenerror 
-               (FLG_WARNLINTCOMMENTS,
-                cstring_makeLiteral
-                ("Traditional lint comment /*NOTREACHED*/ used.  "
-                 "This is interpreted by "
-                 "LCLint in the same way as most Unix lints, but it is "
-                 "preferable to replace it with the /*@notreached@*/ "
-                 "semantic comment."),
-                g_currentloc);
-             
-             return QNOTREACHED;
-           }
-         else if (s_keytable[i].token == QPRINTFLIKE)
-           {
-             setSpecialFunction (qual_createPrintfLike ());
-             return SKIPTOK;
-           }
-         else if (s_keytable[i].token == QLINTPRINTFLIKE)
-           {         
-             voptgenerror 
-               (FLG_WARNLINTCOMMENTS,
-                cstring_makeLiteral
-                ("Traditional lint comment /*PRINTFLIKE*/ used.  "
-                 "This is interpreted by "
-                 "LCLint in the same way as most Unix lints, but it is "
-                 "preferable to replace it with either /*@printflike@*/, "
-                 "/*@scanflike@*/ or /*@messagelike@*/."),
-                g_currentloc);
-             
-             setSpecialFunction (qual_createPrintfLike ());
-             return SKIPTOK;
-           }
-         else if (s_keytable[i].token == QSCANFLIKE)
-           {
-             setSpecialFunction (qual_createScanfLike ());
-             return SKIPTOK;
-           }
-         else if (s_keytable[i].token == QMESSAGELIKE)
-           {
-             setSpecialFunction (qual_createMessageLike ());
-             return SKIPTOK;
-           }
-         else if (s_keytable[i].token == QARGSUSED)
-           {
-             voptgenerror
-               (FLG_WARNLINTCOMMENTS,
-                cstring_makeLiteral
-                ("Traditional lint comment /*ARGSUSED*/ used.  "
-                 "This is interpreted by "
-                 "LCLint in the same way as most Unix lints, but it is "
-                 "preferable to use /*@unused@*/ annotations on "
-                 "the unused parameters."),
-                g_currentloc);
-             
-             setArgsUsed ();
-             return SKIPTOK;
-           }
-         
-         return s_keytable[i].token;
-       }
-      
-      i++;
-    }
-  
-  return BADTOK;
-}
-
-static int lminput ()
-{
-  if (savechar == '\0')
-    {
-      incColumn ();
-      return (input ());
-    }
-  else
-    {
-      int save = (int) savechar;
-      savechar = '\0';
-      return save;
-    }
-}
-
-static void lmsavechar (char c)
-{
-  if (savechar == '\0') savechar = c;
-  else
-    {
-      llbuglit ("lmsavechar: override");
-    }
-}
-
-static int returnFloat (ctype ct, double f)
-{
-  yylval.expr = exprNode_floatLiteral (f, ct, cstring_fromChars (yytext), 
-                                      fileloc_decColumn (g_currentloc, tokLength));
-  tokLength = 0; 
-  return (CCONSTANT);
-}
-
-static int returnInt (ctype ct, long i)
-{
-  ctype c = ct;
-
-  if (ctype_equal (ct, ctype_int))
-    {
-      if (i == 0)
-       {
-         c = context_typeofZero ();
-       }
-      else if (i == 1)
-       {
-         c = context_typeofOne ();
-       }
-    }
-  
-  yylval.expr = exprNode_numLiteral (c, cstring_fromChars (yytext), 
-                                    fileloc_decColumn (g_currentloc, tokLength), i);   
-  tokLength = 0; 
-  return (CCONSTANT);
-}
-
-static int returnChar (char c)
-{
-  yylval.expr = exprNode_charLiteral (c, cstring_fromChars (yytext), 
-                                     fileloc_decColumn (g_currentloc, tokLength));
-  tokLength = 0; 
-  return (CCONSTANT);
-}
-
-static int ninput ()  
-{
-  int c = lminput ();
-
-  if (c != EOF && ((char)c == '\n'))
-    {
-      context_incLineno ();
-    }
-
-  return c;
-}
-
-static char macro_nextChar ()
-{
-  static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE;
-  int ic;
-  char c;
-
-  ic = lminput ();
-  c = char_fromInt (ic);
-  
-  if (!in_quote && !in_char && (c == '\\' || c == BEFORE_COMMENT_MARKER[0]))
-    {
-      if (c == '\\')
-       {
-         while ((c = char_fromInt (lminput ())) != '\0' && c != '\n')
-           {
-             ; /* skip to newline */
-           }
-         
-         context_incLineno ();
-         
-         if (c != '\0')
-           {
-             return macro_nextChar ();
-           }
-         else 
-           {
-             return c;
-           }
-       }
-      else /* if (c == '@') */
-       {
-         llassert (FALSE); /*@i23@*/
-         if (handleLlSpecial () != BADTOK)
-           {
-             llerrorlit (FLG_SYNTAX, "Macro cannot use special syntax");
-           }
-
-         return macro_nextChar ();
-       }
-    }
-  else if (!in_escape && c == '\"')
-    {
-      in_quote = !in_quote;
-    }
-  else if (!in_escape && c == '\'')
-    {
-      in_char = !in_char;
-    }
-  else if ((in_quote || in_char) && c == '\\')
-    {
-      in_escape = !in_escape;
-    }
-  else if ((in_quote || in_char) && in_escape)
-    {
-      in_escape = FALSE;
-    }
-  else if (!in_quote && c == '/')
-    {
-      char c2;
-      
-      if ((c2 = char_fromInt (lminput ())) == '*')
-       {
-         while (c2 != '\0')
-           {
-             while ((c2 = char_fromInt (lminput ())) != '\0'
-                    && c2 != '\n' && c2 != '*')
-               {
-                 ;
-               }
-             
-             if (c2 == '*')
-               {
-                 while ((c2 = char_fromInt (lminput ())) != '\0' 
-                        && c2 == '*')
-                   {
-                     ;
-                   }
-
-                 if (c2 == '/')
-                   {
-                     goto outofcomment;
-                   }
-               }
-             else 
-               {
-                 llfatalerror (cstring_makeLiteral ("Macro: bad comment!"));
-               }
-           }
-       outofcomment:
-         return macro_nextChar ();
-       }
-      else
-       {
-          /*** putchar does not work!  why?  puts to stdio...??! ***/
-          lmsavechar (c2);
-       }
-    }
-  return c;
-}
-
-/*
-** keeps semantic comments
-*/
-
-static char macro_nextCharC ()
-{
-  static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE;
-  char c;
-
-  c = char_fromInt (lminput ());
-
-  if (!in_quote && !in_char && c == '\\')
-    {
-      while ((c = char_fromInt (lminput ())) != '\0' && c != '\n')
-       {
-         ; /* skip to newline */
-       }
-      
-      context_incLineno ();
-      
-      if (c != '\0')
-       {
-         return macro_nextCharC ();
-       }
-      else
-       {
-         return c;
-       }
-    }
-  else if (!in_escape && c == '\"')
-    {
-      in_quote = !in_quote;
-    }
-  else if (!in_escape && c == '\'')
-    {
-      in_char = !in_char;
-    }
-  else if ((in_quote || in_char) && c == '\\')
-    {
-      in_escape = !in_escape;
-    }
-  else if ((in_quote || in_char) && in_escape)
-    {
-      in_escape = FALSE;
-    }
-  else if (!in_quote && c == '/')
-    {
-      char c2;
-      
-      if ((c2 = char_fromInt (lminput ())) == '*')
-       {
-         while (c2 != '\0')
-           {
-             while ((c2 = char_fromInt (lminput ())) != '\0' 
-                    && c2 != '\n' && c2 != '*')
-               {
-                 ;
-               }
-             
-             if (c2 == '*')
-               {
-                 while ((c2 = char_fromInt (lminput ())) != '\0'
-                        && c2 == '*')
-                   {
-                     ;
-                   }
-
-                 if (c2 == '/') 
-                   {
-                     goto outofcomment;
-                   }
-               }
-             else 
-               {
-                 llfatalerror (cstring_makeLiteral ("Macro: bad comment!"));
-               }
-           }
-       outofcomment:
-         return macro_nextCharC ();
-       }
-      else
-       {
-         lmsavechar (c2);
-       }
-    }
-  return c;
-}
-
-/*
-** skips whitespace (handles line continuations)
-** returns first non-whitespace character
-*/
-
-static char skip_whitespace ()
-{
-  char c;
-
-  while ((c = macro_nextChar ()) == ' ' || c == '\t')
-    {
-      ;
-    }
-
-  return c;
-}
-
-static void handleMacro ()
-{
-  cstring mac = cstring_undefined;
-  int macrocode;
-  char c;
-
-  while (currentColumn () > 2)
-    {
-      mac = cstring_appendChar (mac, ' ');
-      setTokLength (-1);
-    }
-
-  c = macro_nextCharC ();
-
-  if (c >= '0' && c <= '9')
-    {
-      int i;
-
-      for (i = 0; i < ((c - '0') + 1); i++)
-       {
-         mac = cstring_appendChar (mac, ' ');
-       }
-    }
-  else
-    {
-      BADBRANCH;
-    }
-
-  while (((c = macro_nextCharC ()) != '\0') && (c != '\n'))
-    {
-      mac = cstring_appendChar (mac, c);
-    }
-
-  
-  macrocode = tokenMacroCode (mac);
-
-  if (macrocode == BADTOK && !isArtificial (mac))
-    {
-      context_addMacroCache (mac);
-    }
-  else
-    {
-      cstring_free (mac);
-    }
-
-  if (c == '\n')
-    {
-      context_incLineno ();
-    }
-}
-
-static bool processMacro (void)
-{
-  uentry e2;
-  ctype ct;
-  int noparams = 0;
-  cstring fname = cstring_undefined;
-  bool res = TRUE;
-  bool isspecfcn = FALSE;
-  bool isiter = FALSE;
-  bool skipparam = FALSE;
-  bool isenditer = FALSE;
-  bool unknownm = FALSE;
-  bool hasParams = FALSE;
-  bool emptyMacro = FALSE;
-  char c = skip_whitespace ();
-  fileloc loc = fileloc_noColumn (g_currentloc);
-
-  /* are both of these necessary?  what do they mean? */
-  uentryList specparams = uentryList_undefined;
-  uentryList pn = uentryList_undefined;
-
-  context_resetMacroMissingParams ();
-
-  if (c == '\0' || c == '\n')
-    {
-      llcontbug (cstring_makeLiteral ("Bad macro"));
-      fileloc_free (loc);
-      return FALSE;
-    }
-  
-  fname = cstring_appendChar (fname, c);  
-
-  while ((c = macro_nextChar ()) != '(' && c != '\0'
-        && c != ' ' && c != '\t' && c != '\n')
-    {
-      fname = cstring_appendChar (fname, c);
-    }
-
-  if (c == ' ' || c == '\t' || c == '\n')
-    {
-      char oldc = c;
-
-      if (c != '\n')
-       {
-         while (c == ' ' || c == '\t')
-           {
-             c = macro_nextChar ();
-           }
-         unput (c);
-       }
-
-      if (c == '\n')
-       {
-         emptyMacro = TRUE;
-         unput (c);
-       }
-
-      c = oldc;
-    }
-
-  hasParams = (c == '(');
-  
-  if (usymtab_exists (fname))
-    {
-      e2 = usymtab_lookupExpose (fname);
-      ct = uentry_getType (e2);
-
-      if (uentry_isCodeDefined (e2) 
-         && fileloc_isUser (uentry_whereDefined (e2)))
-       {
-         if (optgenerror 
-             (FLG_MACROREDEF,
-              message ("Macro %s already defined", fname),
-              loc))
-           {
-             uentry_showWhereDefined (e2);
-             uentry_clearDefined (e2);
-           }
-
-         if (uentry_isFunction (e2))
-           {
-             uentry_setType (e2, ctype_unknown);
-             ct = ctype_unknown;
-             unknownm = TRUE;
-             context_enterUnknownMacro (e2); 
-           }
-         else
-           {
-             context_enterConstantMacro (e2);
-           }
-       }
-      else
-       {
-         if (uentry_isForward (e2) && uentry_isFunction (e2))
-           {
-             unknownm = TRUE;
-
-             voptgenerror 
-               (FLG_MACROFCNDECL,
-                message
-                ("Parameterized macro has no prototype or specification: %s ", 
-                 fname),
-                loc);
-             
-             ct = ctype_unknown;
-             uentry_setType (e2, ctype_unknown);
-             uentry_setFunctionDefined (e2, loc); 
-             uentry_setUsed (e2, fileloc_undefined);
-             context_enterUnknownMacro (e2); 
-           }
-         else
-           {
-             if (uentry_isIter (e2))
-               {
-                 isiter = TRUE;
-                 specparams = uentry_getParams (e2);
-                 noparams = uentryList_size (specparams);
-                 uentry_setDefined (e2, loc);
-                 context_enterIterDef (e2); 
-               }
-             else if (uentry_isEndIter (e2))
-               {
-                 isenditer = TRUE;
-                 uentry_setDefined (e2, loc);
-                 context_enterIterEnd (e2); /* don't care about it now */
-                 /* but should parse like an iter! */
-               }
-             else if (uentry_isConstant (e2))
-               {
-                 if (hasParams)
-                   {
-                     voptgenerror 
-                       (FLG_INCONDEFS, 
-                        message ("Constant %s implemented as parameterized macro",
-                                 fname),
-                        g_currentloc);
-                     
-                     uentry_showWhereSpecified (e2);
-                     uentry_setType (e2, ctype_unknown);
-                     uentry_makeConstantFunction (e2);
-                     uentry_setDefined (e2, g_currentloc);
-                     uentry_setFunctionDefined (e2, g_currentloc);
-                     context_enterUnknownMacro (e2); 
-                   }
-                 else
-                   {
-                     if (!uentry_isSpecified (e2))
-                       {
-                         fileloc oloc = uentry_whereDeclared (e2);
-
-                         if (fileloc_isLib (oloc))
-                           {
-                             ;
-                           }
-                         else if (fileloc_isUndefined (oloc)
-                                  || fileloc_isPreproc (oloc))
-                           {
-                             if (!emptyMacro)
-                               {
-                                 voptgenerror
-                                   (FLG_MACROCONSTDECL,
-                                    message 
-                                    ("Macro constant %q not declared",
-                                     uentry_getName (e2)),
-                                    loc);                       
-                               }
-                           }
-                         else if (!fileloc_withinLines (oloc, loc, 2))
-                           { /* bogus!  will give errors if there is too much whitespace */
-                             voptgenerror
-                               (FLG_SYNTAX,
-                                message 
-                                ("Macro constant name %s does not match name in "
-                                 "previous constant declaration.  This constant "
-                                 "is declared at %q", fname, 
-                                 fileloc_unparse (oloc)),
-                                loc);
-                           }
-                       }
-
-                     context_enterConstantMacro (e2);        
-                     cstring_free (fname);
-                     fileloc_free (loc);
-                     return res;
-                   }
-
-               }
-             else if (ctype_isFunction (ct))
-               {
-                 isspecfcn = TRUE;
-                 specparams = ctype_argsFunction (ct);
-                 noparams = uentryList_size (specparams);
-                 
-                 uentry_setFunctionDefined (e2, loc); 
-                 context_enterMacro (e2);
-               }
-             else if (uentry_isVar (e2))
-               {
-                 if (hasParams)
-                   {
-                     voptgenerror
-                       (FLG_INCONDEFS,
-                        message ("Variable %s implemented as parameterized macro", 
-                                 fname),
-                        loc);
-
-                     uentry_showWhereSpecified (e2);
-                     uentry_setType (e2, ctype_unknown);
-                     uentry_makeVarFunction (e2);
-                     uentry_setDefined (e2, g_currentloc);
-                     uentry_setFunctionDefined (e2, g_currentloc);
-                     context_enterUnknownMacro (e2); 
-                   }
-                 else
-                   {
-                     uentry ucons = uentry_makeConstant (fname,
-                                                         ctype_unknown,
-                                                         loc);
-                     if (uentry_isExpandedMacro (e2))
-                       {
-                         ; /* okay */
-                       }
-                     else
-                       {
-                         if (optgenerror 
-                             (FLG_INCONDEFS,
-                              message ("Variable %s implemented by a macro",
-                                       fname),
-                              loc))
-                           {
-                             uentry_showWhereSpecified (e2);
-                           }
-                       }
-
-                     uentry_setDefined (e2, loc);
-                     uentry_setUsed (ucons, loc);
-
-                     context_enterConstantMacro (ucons);
-                     uentry_markOwned (ucons);
-                     cstring_free (fname);
-                     return res;
-                   }
-               }
-             else
-               {
-                 if (uentry_isDatatype (e2))
-                   {
-                     vgenhinterror 
-                       (FLG_SYNTAX,
-                        message ("Type implemented as macro: %x", 
-                                 uentry_getName (e2)),
-                        message ("A type is implemented using a macro definition.  A "
-                                 "typedef should be used instead."),
-                        g_currentloc);
-
-                     swallowMacro ();
-                     /* Must exit scope (not sure why a new scope was entered?) */
-                     usymtab_quietExitScope (g_currentloc);
-                     uentry_setDefined (e2, g_currentloc);
-                     res = FALSE;
-                   }
-                 else
-                   {
-                     llcontbug 
-                       (message ("Unexpanded macro not function or constant: %q", 
-                                 uentry_unparse (e2)));
-                     uentry_setType (e2, ctype_unknown);
-                     
-                     if (hasParams)
-                       {
-                         uentry_makeVarFunction (e2);
-                         uentry_setDefined (e2, g_currentloc);
-                         uentry_setFunctionDefined (e2, g_currentloc);
-                         context_enterUnknownMacro (e2); 
-                       }
-                   }
-               }
-           }
-       }
-    }
-  else
-    {
-      uentry ce;
-
-      /* evans 2001-09-09 - if it has params, assume a function */
-      if (hasParams)
-       {
-         voptgenerror 
-           (FLG_MACROMATCHNAME,
-            message ("Unexpanded macro %s does not match name of a declared "
-                     "function. The name used in the control "
-                     "comment on the previous line should match.",
-                     fname),
-            loc);
-         
-         ce = uentry_makeFunction (fname, ctype_unknown, 
-                                   typeId_invalid,
-                                   globSet_undefined,
-                                   sRefSet_undefined,
-                                   warnClause_undefined,
-                                   fileloc_undefined);      
-         uentry_setUsed (ce, loc); /* perhaps bogus? */
-         e2 = usymtab_supEntryReturn (ce);
-         context_enterUnknownMacro (e2);             
-       }
-      else
-       {
-         voptgenerror 
-           (FLG_MACROMATCHNAME,
-            message ("Unexpanded macro %s does not match name of a constant "
-                     "or iter declaration.  The name used in the control "
-                     "comment on the previous line should match.  "
-                     "(Assuming macro defines a constant.)", 
-                     fname),
-            loc);
-         
-         ce = uentry_makeConstant (fname, ctype_unknown, fileloc_undefined);      
-         uentry_setUsed (ce, loc); /* perhaps bogus? */
-         e2 = usymtab_supEntryReturn (ce);
-         
-         context_enterConstantMacro (e2);            
-         cstring_free (fname);
-         fileloc_free (loc);
-         return res;
-       }
-    }
-  
-  /* in macros, ( must follow immediatetly after name */
-  
-  if (hasParams)
-    {
-      int paramno = 0;
-      
-      c = skip_whitespace ();
-
-      while (c != ')' && c != '\0')
-       {
-         uentry  param;
-         bool    suppress = context_inSuppressRegion ();
-         cstring paramname = cstring_undefined;
-
-         /*
-         ** save the parameter location
-         */
-
-         decColumn ();
-         context_saveLocation ();
-         incColumn ();
-
-         while (c != ' ' && c != '\t' && c != ',' && c != '\0' && c != ')')
-           {
-             paramname = cstring_appendChar (paramname, c);
-             c = macro_nextChar ();
-           }
-         
-         if (c == ' ' || c == '\t') c = skip_whitespace ();
-
-         if (c == ',')
-           {
-             c = macro_nextChar ();
-             if (c == ' ' || c == '\t') c = skip_whitespace ();
-           }
-         
-         if (c == '\0')
-           {
-             llfatalerror (cstring_makeLiteral
-                           ("Bad macro syntax: uentryList"));
-           }
-         
-         if ((isspecfcn || isiter) && (paramno < noparams)
-             && !uentry_isElipsisMarker (uentryList_getN 
-                                         (specparams, paramno)))
-           {
-             fileloc sloc = context_getSaveLocation ();
-             uentry decl = uentryList_getN (specparams, paramno);
-             sRef sr;
-             
-             param = uentry_nameCopy (paramname, decl);
-                             
-             uentry_setParam (param);
-             sr = sRef_makeParam (paramno, uentry_getType (param), stateInfo_makeLoc (sloc));
-
-             if (sRef_getNullState (sr) == NS_ABSNULL)
-               {
-                 ctype pt = ctype_realType (uentry_getType (param));
-
-                 if (ctype_isUser (pt))
-                   {
-                     uentry te = usymtab_getTypeEntrySafe (ctype_typeId (pt));
-                     
-                     if (uentry_isValid (te))
-                       {
-                         sRef_setStateFromUentry (sr, te);
-                       }
-                   }
-                 else
-                   {
-                     sRef_setNullState (sr, NS_UNKNOWN, sloc);
-                   }
-               }
-
-             uentry_setSref (param, sr);
-             uentry_setDeclaredForceOnly (param, sloc);
-
-             skipparam = isiter && uentry_isOut (uentryList_getN (specparams, paramno));
-           }
-         else
-           {
-             fileloc sloc = context_getSaveLocation ();
-
-             param = uentry_makeVariableSrefParam 
-               (paramname, ctype_unknown, fileloc_copy (sloc), 
-                sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (sloc)));
-             DPRINTF (("Unknown param: %s", uentry_unparseFull (param)));
-             cstring_free (paramname);
-
-             sRef_setPosNull  (uentry_getSref (param), sloc);
-             uentry_setDeclaredForce (param, sloc);
-
-             skipparam = FALSE;
-             fileloc_free (sloc);
-           }
-
-         if (!skipparam)
-           {
-             llassert (!uentry_isElipsisMarker (param));
-
-             if (!suppress)
-               {
-                 sRef_makeUnsafe (uentry_getSref (param));
-               }
-             
-             pn = uentryList_add (pn, uentry_copy (param));
-             usymtab_supEntry (param);
-           }
-         else
-           {
-             /* don't add param */
-             uentry_free (param);
-           }
-
-         if (c == ',') 
-           {
-             (void) macro_nextChar ();
-             c = skip_whitespace ();
-           }
-
-         paramno++;
-       }
-      
-      if (c == ')')
-       {
-         if (isspecfcn || isiter)
-           {
-             if (paramno != noparams && noparams >= 0)
-               {
-                 advanceLine ();
-
-                 voptgenerror 
-                   (FLG_INCONDEFS,
-                    message ("Macro %s specified with %d args, defined with %d", 
-                             fname, noparams, paramno),
-                    g_currentloc);
-
-                 uentry_showWhereSpecified (e2);
-                 uentry_resetParams (e2, pn);
-               }
-           }
-         else
-           {
-             uentry_resetParams (e2, pn);
-           }
-       }
-    }
-  else
-    {
-      /*
-      ** the form should be:
-      **
-      ** # define newname oldname
-      ** where oldname refers to a function matching the specification
-      ** of newname.
-      */
-
-      if (unknownm)
-       {
-         sRef_setGlobalScope ();
-         usymtab_supGlobalEntry (uentry_makeVariableLoc (fname, ctype_unknown));
-         sRef_clearGlobalScope ();
-       }
-      else
-       {
-         context_setMacroMissingParams ();
-       }
-    }
-  
-  
-  /* context_setuentryList (pn); */
-  usymtab_enterScope ();
-
-  fileloc_free (loc);
-  cstring_free (fname);
-
-  return res;
-}
-
-static bool handleSpecial (char *yyt)
-{
-  char *l = mstring_create (MAX_NAME_LENGTH);
-  static bool reportcpp = FALSE;
-  int lineno = 0;
-  char c;
-  char *ol;
-  cstring olc;
-  
-  strcpy (l, yyt + 1);
-
-  /* Need to safe original l for deallocating. */
-  ol = l;
-
-  l += strlen (yyt) - 1;
-  
-  while ((c = char_fromInt (lminput ())) != '\n' && c != '\0')
-    {
-      *l++ = c;
-    }
-
-  *l = '\0';
-  olc = cstring_fromChars (ol);
-  
-  if (cstring_equalPrefixLit (olc, "pragma"))
-    {
-      char *pname = mstring_create (longUnsigned_fromInt (MAX_PRAGMA_LEN));
-      char *opname = pname;
-      char *ptr = ol + 6; /* pragma is six characters, plus space */
-      int len = 0;
-      
-      
-      /* skip whitespace */
-      while (((c = *ptr) != '\0') && isspace (c))
-       {
-         ptr++;
-       }
-
-      
-      while (((c = *ptr) != '\0') && !isspace (c))
-       {
-         len++;
-
-         if (len > MAX_PRAGMA_LEN)
-           {
-             break;
-           }
-
-         ptr++;
-         *pname++ = c;
-       }
-
-      *pname = '\0';
-      
-      if (len == PRAGMA_LEN_EXPAND 
-         && mstring_equal (opname, PRAGMA_EXPAND))
-       {
-         cstring exname = cstring_undefined;
-         uentry ue;
-         
-         ptr++; 
-         while (((c = *ptr) != '\0') && !isspace (c))
-           {
-             exname = cstring_appendChar (exname, c);
-             ptr++;
-           }
-            
-         
-         ue = usymtab_lookupExposeGlob (exname);
-         
-         if (uentry_isExpandedMacro (ue))
-           {
-             if (fileloc_isPreproc (uentry_whereDefined (ue)))
-               {
-                 fileloc_setColumn (g_currentloc, 1);
-                 uentry_setDefined (ue, g_currentloc);
-               }
-           }
-
-         cstring_free (exname);
-       }
-    }
-  else if (cstring_equalPrefixLit (olc, "ident"))
-    {
-      /* Some pre-processors will leave these in the code.  Ignore rest of line */
-    }
-  /*
-  ** Yuk...Win32 filenames can have spaces in them...we need to read
-  ** to the matching end quote.
-  */
-  else if ((sscanf (ol, "line %d \"", &lineno) == 1)
-          || (sscanf (ol, " %d \"", &lineno) == 1))
-    {
-      char *tmp = ol;
-      cstring fname;
-      fileId fid;
-
-      /*@access cstring@*/
-      while (*tmp != '\"' && *tmp != '\0')
-       {
-         tmp++;
-       }
-
-      llassert (*tmp == '\"');
-
-      tmp++;
-
-      fname = tmp;
-      
-      while (*tmp != '\"' && *tmp != '\0')
-       {
-         tmp++;
-       }
-
-      llassert (*tmp == '\"');
-
-      *tmp = '\0';
-
-# if defined(OS2) || defined(MSDOS) || defined(WIN32)
-
-      /*
-      ** DOS-like path delimiters get delivered in pairs, something like 
-      ** \"..\\\\file.h\", so we have to make it normal again. We do NOT
-      ** remove the pre dirs yet as we usually specify tmp paths relative
-      ** to the current directory, so tmp files would not get found in
-      ** the hash table.  If this method fails we try it again later. 
-      */
-
-      {
-       char *stmp = fname;
-       
-       /*
-       ** Skip past the drive marker.
-       */
-       
-       if (strchr (stmp, ':') != NULL)
-         {
-           stmp = strchr (stmp, ':') + 1;
-         }
-       
-       while ((stmp = strchr (stmp, CONNECTCHAR)) != NULL )
-         {
-           if (*(stmp+1) == CONNECTCHAR)
-             {
-               memmove (stmp, stmp+1, strlen (stmp));
-             }
-           
-           stmp++;
-         }
-       
-       fid = fileTable_lookupBase (context_fileTable (), fname);
-       if (!(fileId_isValid (fid)))
-         {
-           fname = removePreDirs (fname);
-           fid = fileTable_lookupBase (context_fileTable (), fname);
-         }
-      }
-# else  /* !defined(OS2) && !defined(MSDOS) */
-      fname = removePreDirs (fname);
-      fid = fileTable_lookupBase (context_fileTable (), fname);      
-# endif /* !defined(OS2) && !defined(MSDOS) */
-      
-      if (!(fileId_isValid (fid)))
-       {
-         if (context_inXHFile ())
-           {
-             fid = fileTable_addXHFile (context_fileTable (), fname);
-           }
-         else if (isHeaderFile (fname))
-           {
-             fid = fileTable_addHeaderFile (context_fileTable (), fname);
-           }
-         else
-           {
-             fid = fileTable_addFile (context_fileTable (), fname);
-           }
-       }
-      
-      setFileLine (fid, lineno);
-      /*@noaccess cstring@*/
-    }
-  else if ((sscanf (ol, "line %d", &lineno) == 1) 
-          || (sscanf (ol, " %d", &lineno) == 1))
-    {
-      setLine (lineno); /* next line is <cr> */
-    }
-  else
-    {
-      if (mstring_equal (ol, "")) {
-       DPRINTF (("Empty pp command!"));
-       /*
-       ** evs 2000-05-16: This is a horrible kludge, to get around a bug (well, difficulty) in the pre-processor.
-       ** We handle a plain # in the input file, by echoing it, and ignoring it in the post-pp-file.
-       */
-       mstring_free (ol);
-       return FALSE;
-      } else {
-       if (!reportcpp)
-         {
-           
-         } else {
-           llbug (message ("File contains preprocessor command: #%s", 
-                           cstring_fromChars (ol)));
-           reportcpp = TRUE;
-         }
-      }
-      
-      sfree (ol);
-      return TRUE;
-    }
-
-  sfree (ol);
-  return FALSE;
-}
-  
-static int handleLlSpecial ()
-{ 
-  bool hasnl = FALSE;
-  int ic; 
-  char c;
-  char *s = mstring_createEmpty ();
-  char *os; 
-  int tok;
-  int charsread = 0;
-  fileloc loc;
-
-  loc = fileloc_copy (g_currentloc);
-  DPRINTF (("Handle special: %s", fileloc_unparse (loc)));
-
-  while (((ic = ninput ()) != 0) && isalpha (ic))
-    {
-      c = (char) ic;
-      s = mstring_append (s, c);
-      charsread++;
-    }
-
-  DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));
-  os = s;
-
-  if (charsread == 0 && ic == (int) AFTER_COMMENT_MARKER[0])
-    {
-      ic = ninput ();
-
-      llassert (ic == AFTER_COMMENT_MARKER[1]);
-            
-      if (*s == '\0')
-       {
-         sfree (os);
-         fileloc_free (loc);
-         return QNOMODS; /* special token no modifications token */
-       }
-    }
-  
-  DPRINTF (("Coment marker: %s", os));
-  tok = commentMarkerToken (cstring_fromChars (os));
-
-  if (tok != BADTOK)
-    {
-      tokLength = charsread;
-      sfree (os);
-      inSpecPart = TRUE;
-      fileloc_free (loc);
-      return tok;
-    }
-
-  DPRINTF (("Not a comment marker..."));
-  /* Add rest of the comment */
-  
-  if (ic != 0 && ic != EOF)
-    {
-      c = (char) ic;
-      
-      s = mstring_append (s, c);
-      charsread++;
-
-      while (((ic = ninput ()) != 0) && (ic != EOF)
-            && (ic != AFTER_COMMENT_MARKER[0]))
-       {
-         c = (char) ic;
-
-         /* evans 2001-09-01 added to prevent assertion failures for uncloses syntactic comments */
-
-         if (c == '\n') {
-           hasnl = TRUE; /* This prevents tokLength from being set later. */
-           tokLength = 0; 
-
-           voptgenerror
-             (FLG_SYNTAX, 
-              message ("Likely parse error: syntactic comment token spans multiple lines: %s",
-                       cstring_fromChars (s)),
-              g_currentloc);
-         }
-
-         s = mstring_append (s, c);
-         charsread++;
-       }
-    }
-
-  DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));
-
-  if (ic == AFTER_COMMENT_MARKER[0]) 
-    {
-      int nc = ninput ();
-      llassert ((char) nc ==  AFTER_COMMENT_MARKER[1]);
-      charsread++;
-    }
-
-  os = s;
-
-  while (*s == ' ' || *s == '\t' || *s == '\n') 
-    {
-      s++;
-    }
-
-  if (*s == '-' || *s == '+' || *s == '=') /* setting flags */
-    {
-      c = *s;
-
-      while (c == '-' || c == '+' || c == '=')
-       {
-         ynm set = ynm_fromCodeChar (c);
-         cstring thisflag;
-
-         s++;
-         
-         thisflag = cstring_fromChars (s);
-         
-         while ((c = *s) != '\0' && (c != '-') && (c != '=')
-                && (c != '+') && (c != ' ') && (c != '\t') && (c != '\n'))
-           {
-             s++;
-           }
-
-         *s = '\0';
-
-         if (!context_getFlag (FLG_NOCOMMENTS))
-           {
-             cstring flagname = thisflag;
-             flagcode fflag = identifyFlag (flagname);
-               
-             if (flagcode_isSkip (fflag))
-               {
-                 ;
-               }
-             else if (flagcode_isInvalid (fflag))
-               {
-                 if (isMode (flagname))
-                   {
-                     if (ynm_isMaybe (set))
-                       {
-                         llerror
-                           (FLG_BADFLAG, 
-                            message 
-                            ("Semantic comment attempts to restore flag %s.  "
-                             "A mode flag cannot be restored.",
-                             flagname));
-                       }
-                     else
-                       {
-                         context_setMode (flagname);
-                       }
-                   }
-                 else
-                   {
-                     voptgenerror
-                       (FLG_UNRECOGFLAGCOMMENTS,
-                        message ("Unrecognized option in semantic comment: %s", 
-                                 flagname),
-                        g_currentloc);
-                   }
-               }
-             else if (flagcode_isGlobalFlag (fflag))
-               {
-                 voptgenerror
-                   (FLG_BADFLAG, 
-                    message 
-                    ("Semantic comment attempts to set global flag %s.  "
-                     "A global flag cannot be set locally.",
-                     flagname),
-                    g_currentloc);
-               }
-             else
-               {
-                 context_fileSetFlag (fflag, set);
-                 
-                 if (flagcode_hasArgument (fflag))
-                   {
-                     if (ynm_isMaybe (set))
-                       {
-                         voptgenerror
-                           (FLG_BADFLAG, 
-                            message 
-                            ("Semantic comment attempts to restore flag %s.  "
-                             "A flag for setting a value cannot be restored.",
-                             flagname),
-                            g_currentloc);
-                       }
-                     else
-                       { /* cut-and-pastied from llmain...blecch */
-                         cstring extra = cstring_undefined;
-                         char *rest;
-                         char *orest;
-                         char rchar;
-                         
-                         *s = c;
-                         rest = mstring_copy (s);
-                         orest = rest;
-                         *s = '\0';
-                         
-                         while ((rchar = *rest) != '\0'
-                                && (isspace (rchar)))
-                           {
-                             rest++;
-                             s++;
-                           }
-                         
-                         while ((rchar = *rest) != '\0'
-                                && !isspace (rchar))
-                           {
-                             extra = cstring_appendChar (extra, rchar);
-                             rest++; 
-                             s++;
-                           }
-                         
-                         sfree (orest);
-                         
-                         if (cstring_isUndefined (extra))
-                           {
-                             llerror 
-                               (FLG_BADFLAG,
-                                message
-                                ("Flag %s (in semantic comment) must be followed by an argument",
-                                 flagcode_unparse (fflag)));
-                           }
-                         else
-                           {
-                             s--;
-                             
-                             if (flagcode_hasValue (fflag))
-                               {
-                                 setValueFlag (fflag, extra);
-                               }
-                             else if (flagcode_hasString (fflag))
-                               {
-                                 setStringFlag (fflag, extra);
-                               }
-                             else
-                               {
-                                 BADEXIT;
-                               }
-                           }
-                       }
-                   }
-               }
-           }
-         else
-           {
-             ;
-           }
-
-         *s = c;
-         while ((c == ' ') || (c == '\t') || (c == '\n'))
-           {
-             c = *(++s);
-           }
-       } 
-
-      if (context_inHeader () && !isArtificial (cstring_fromChars (os)))
-       {
-         DPRINTF (("Here adding comment: %s", os));
-         context_addComment (cstring_fromCharsNew (os));
-       }
-      else
-       {
-         ;
-       }
-    }
-  else
-    {
-      char *t = s;
-      int macrocode;
-      char tchar = '\0';
-      annotationInfo ainfo;
-
-      while (*s != '\0' && *s != ' ' && *s != '\t' && *s != '\n') 
-       {
-         s++;
-       }
-
-      if (*s != '\0') 
-       {
-         tchar = *s;
-         *s = '\0';
-         s++;
-       }
-      
-      t = cstring_toCharsSafe (cstring_downcase (cstring_fromChars (t)));
-      macrocode = tokenMacroCode (cstring_fromChars (t));
-
-      if (macrocode != BADTOK)
-       {
-         tokLength = hasnl ? 0 : mstring_length (t);
-         
-         sfree (t);
-         sfree (os);
-         fileloc_free (loc);
-
-         if (macrocode == SKIPTOK)
-           {
-             return BADTOK;
-           }
-
-         return macrocode;
-       }
-      
-      ainfo = context_lookupAnnotation (cstring_fromChars (os));
-      
-      if (annotationInfo_isDefined (ainfo)) {
-       DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));
-       /*@i324@*/ yylval.annotation = ainfo;
-       tokLength = 0;
-       sfree (os);
-       sfree (t);
-       fileloc_free (loc);
-       return CANNOTATION;
-      } 
-
-      if (context_inHeader ())
-       {
-         if (tchar != '\0')
-           {
-             *(s-1) = tchar;
-           }
-         
-         if ((context_inMacro () || context_inGlobalContext ())
-             && macrocode != SKIPTOK
-             && !isArtificial (cstring_fromChars (os))) 
-           {
-             DPRINTF (("Add comment: %s", os));
-             context_addComment (cstring_fromCharsNew (os));
-           }
-         else
-           {
-             ; 
-           }
-         
-         if (tchar != '\0')
-           {
-             *(s-1) = '\0';
-           }
-       }
-
-      if (mstring_equal (t, "ignore"))
-       {
-         if (!context_getFlag (FLG_NOCOMMENTS))
-           {
-             context_enterSuppressRegion ();
-           }
-       }
-      else if ((*t == 'i' || *t == 't')
-              && (*(t + 1) == '\0'))
-       {
-         if (!context_getFlag (FLG_NOCOMMENTS)
-             && (*t == 'i' || context_getFlag (FLG_TMPCOMMENTS)))
-           {
-             context_enterSuppressLine (-1); /* infinite suppression */
-           }
-       }
-      else if (((*t == 'i') || (*t == 't'))
-              && ((*(t + 1) >= '0' && *(t + 1) <= '9')))
-       {
-         bool tmpcomment = (*t == 't');
-         int val = -1; 
-         char *tt = t; /* don't mangle t, since it is free'd */
-         char lc = *(++tt);
-
-         if (lc >= '0' && lc <= '9')
-           {
-             val = (int)(lc - '0');
-             
-             lc = *(++tt);       
-             while (lc >= '0' && lc <= '9')
-               {
-                 val *= 10;
-                 val += lc - '0';
-                 lc = *(++tt);
-               }
-           }
-
-         
-         if (!context_getFlag (FLG_NOCOMMENTS)
-             && (!tmpcomment || context_getFlag (FLG_TMPCOMMENTS)))
-           {
-             context_enterSuppressLine (val);
-           }
-       }
-      else if (mstring_equal (t, "end"))
-       {
-         if (!context_getFlag (FLG_NOCOMMENTS))
-           {
-             context_exitSuppressRegion ();
-           }
-       }
-      else if (mstring_equal (t, "notfunction"))
-       {
-        ; /* handled by pcpp */
-       }
-      else if (mstring_equal (t, "access"))
-       {
-         cstring tname;
-         
-         while (TRUE)
-           {
-             while ((c = *s) && (c == ' ' || c == '\t' || c == '\n'))
-               {
-                 s++;
-               }
-             
-             if (c == '\0')
-               {
-                   break;
-               }
-
-             tname = cstring_fromChars (s);
-             
-             while ((c = *s) != '\0' && c != ' ' 
-                    && c != '\t' && c != '\n' && c != ',') 
-               {
-                 s++;
-               }
-
-             *s = '\0';
-
-             DPRINTF (("Access %s", tname));
-
-             if (!context_getFlag (FLG_NOCOMMENTS) 
-                 && !context_getFlag (FLG_NOACCESS))
-               {
-                 if (usymtab_existsType (tname))
-                   {
-                     typeId uid = usymtab_getTypeId (tname);
-                     uentry ue = usymtab_getTypeEntry (uid);
-
-                     if (uentry_isAbstractDatatype (ue))
-                       {
-                         context_addFileAccessType (uid);
-                         DPRINTF (("Adding access to: %s / %d", tname, uid));
-                       }
-                     else
-                       {
-                         voptgenerror
-                           (FLG_COMMENTERROR,
-                            message
-                            ("Non-abstract type %s used in access comment",
-                             tname),
-                            g_currentloc);
-                       }
-                   }
-                 else
-                   {
-                     if (!(context_inSuppressRegion ()
-                           || context_inSuppressZone (g_currentloc)))
-                       {
-                         voptgenerror
-                           (FLG_COMMENTERROR,
-                            message
-                            ("Unrecognized type %s used in access comment",
-                             tname),
-                            g_currentloc);
-                       }
-                   }
-               }
-             
-             if (c != '\0') 
-               {
-                 s++;
-               }
-             
-             if (c != ',' && c != ' ')
-               {
-                 break;
-               }
-           }
-       }
-      else if (mstring_equal (t, "noaccess"))
-       {
-         cstring tname;
-         char lc;
-         
-         while (TRUE)
-           {
-             while ((lc = *s) && (lc == ' ' || lc == '\t' || lc == '\n')) 
-               {
-                 s++;
-               }
-             
-             if (lc == '\0')
-               {
-                break;
-               }
-
-             tname = cstring_fromChars (s);
-             
-             while ((lc = *s) != '\0' && lc != ' ' && lc != '\t' 
-                    && lc != '\n' && lc != ',') 
-               {
-                 s++;
-               }
-
-             *s = '\0';
-
-             if (!context_getFlag (FLG_NOCOMMENTS) 
-                 && !context_getFlag (FLG_NOACCESS))
-               {
-                 if (usymtab_existsType (tname))
-                   {
-                     typeId tuid = usymtab_getTypeId (tname);
-                     
-                     if (context_couldHaveAccess (tuid))
-                       {
-                         DPRINTF (("Removing access: %s", tname));
-                         context_removeFileAccessType (tuid);
-                       }
-                     else
-                       {
-                         if (!(context_inSuppressRegion () 
-                               || context_inSuppressZone (g_currentloc)))
-                           {
-                             uentry ue = usymtab_getTypeEntry (tuid);
-                             
-                             if (uentry_isAbstractDatatype (ue))
-                               {
-                                 voptgenerror
-                                   (FLG_COMMENTERROR,
-                                    message
-                                    ("Non-accessible abstract type %s used in noaccess comment",
-                                     tname),
-                                    g_currentloc);
-                               }
-                             else
-                               {
-                                 voptgenerror
-                                   (FLG_COMMENTERROR,
-                                    message
-                                    ("Non-abstract type %s used in noaccess comment",
-                                     tname),
-                                    g_currentloc);
-                               }
-                           }
-                       }
-                   }
-                 else
-                   {
-                     if (!(context_inSuppressRegion () 
-                           || context_inSuppressZone (g_currentloc)))
-                       {
-                         voptgenerror
-                           (FLG_COMMENTERROR,
-                            message
-                            ("Unrecognized type %s used in noaccess comment",
-                             tname),
-                            g_currentloc);
-                       }
-                   }
-               }
-             
-             if (lc != '\0') 
-               {
-                 s++;
-               }
-             
-             if (lc != ',' && lc != ' ')
-               {
-                 break;
-               }
-           }
-       }
-      else
-       {
-         voptgenerror (FLG_UNRECOGCOMMENTS, 
-                       message ("Semantic comment unrecognized: %s", 
-                                cstring_fromChars (os)), loc);
-       }
-
-      sfree (t);
-    }
-  
-  sfree (os);
-  fileloc_free (loc);
-  return BADTOK;
-}
-
-static /*@only@*/ cstring makeIdentifier (char *s)
-{
-  char *c = mstring_create (size_toInt (strlen (s)) + 1);
-  cstring id = cstring_fromChars (c);
-
-  while (isalnum (*s) || (*s == '_') || (*s == '$')) 
-    {
-      *c++ = *s++;
-    }
-
-  *c = '\0';
-  return (id);
-}
-
-/*@observer@*/ /*@dependent@*/ uentry coerceId (cstring cn)
-{
-  if (!(usymtab_exists (cn)))
-    {
-      fileloc loc = fileloc_createExternal ();
-      
-      /*
-      ** We need to put this in a global scope, otherwise the sRef will be deallocated.
-      */
-      
-      uentry ce = uentry_makeUnrecognized (cn, loc);
-      
-      if (!context_inIterEnd ())
-       {
-         voptgenerror 
-           (FLG_SYSTEMUNRECOG, 
-            message ("Unrecognized (possibly system) identifier: %q", 
-                     uentry_getName (ce)), 
-            g_currentloc);
-       }
-      
-      return ce;
-    }
-  
-  return (usymtab_lookup (cn));
-}
-
-/*
-** like, coerceId, but doesn't supercede for iters
-*/
-
-/*@observer@*/ uentry coerceIterId (cstring cn)
-{
-  if (!(usymtab_exists (cn)))
-    {
-      return uentry_undefined;
-    }
-  
-  return (usymtab_lookup (cn));
-}
-
-/*@observer@*/ cstring LastIdentifier ()
-{
-  return (lastidprocessed);
-}
-
-static int processIdentifier (cstring id)
-{
-  uentry le;
-
-  if (context_getFlag (FLG_GRAMMAR))
-    {
-      lldiagmsg (message ("Process identifier: %s", id));
-    }
-
-  context_clearJustPopped ();
-  lastidprocessed = id; 
-
-  if (context_inFunctionHeader ())
-    {
-      int tok = commentMarkerToken (id);
-      DPRINTF (("in function decl..."));
-
-      if (tok != BADTOK)
-       {
-         return tok;
-       }
-      else 
-       {
-         tok = tokenMacroCode (id);
-
-         if (tok != BADTOK)
-           {
-             return tok;
-           }
-         else 
-           {
-             annotationInfo ainfo;
-
-             if (expectingMetaStateName) 
-               {
-                 metaStateInfo msinfo = context_lookupMetaStateInfo (id);
-
-                 if (metaStateInfo_isDefined (msinfo))
-                   {
-                     yylval.msinfo = msinfo;
-                     return METASTATE_NAME;
-                   }
-                 else
-                   {
-                     DPRINTF (("Not meta state name: %s", cstring_toCharsSafe (id)));
-                   }
-               }
-             
-             ainfo = context_lookupAnnotation (id);
-             
-             if (annotationInfo_isDefined (ainfo)) 
-               {
-                 DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));
-                 /*@i324@*/ yylval.annotation = ainfo;
-                 return CANNOTATION;
-               }
-             else
-               {
-                 DPRINTF (("Not annotation: %s", id));
-               }
-           }
-       }
-    }
-
-  /* Consider handling: Defined by C99 as static const char __func__[] */
-
-  if (context_getFlag (FLG_GNUEXTENSIONS))
-    {
-      int tok = BADTOK;
-      
-      if (cstring_equalLit (id, "__stdcall")
-         || cstring_equalLit (id, "__cdecl")
-         || cstring_equalLit (id, "__extension__"))
-       {
-         return BADTOK;
-       }
-      else if (cstring_equalLit (id, "__volatile__"))
-       {
-         tok = QVOLATILE;
-       }
-      else if (cstring_equalLit (id, "__signed"))
-       {
-         tok = QSIGNED;
-       }
-      else if (cstring_equalLit (id, "__unsigned"))
-       {
-         tok = QUNSIGNED;
-       }
-      else if (cstring_equalLit (id, "__const__"))
-       {
-         tok = QCONST;
-       }
-      else if (cstring_equalLit (id, "__alignof__")) 
-       {
-         tok = CALIGNOF; /* alignof is parsed like sizeof */
-       }
-      else if (cstring_equalLit (id, "__FUNCTION__")
-              || cstring_equalLit (id, "__PRETTY_FUNCTION__")) 
-       {
-         /* These tokens hold the name of the current function as strings */
-         yylval.expr = exprNode_stringLiteral (id, fileloc_copy (g_currentloc));
-         tokLength = 0;
-         lastWasString = TRUE;
-         tok = CCONSTANT;
-         return tok;
-       }
-      else if (cstring_equalLit (id, "__attribute__")
-              || cstring_equalLit (id, "__asm__")
-              || cstring_equalLit (id, "_asm")
-              || cstring_equalLit (id, "__asm")
-              || cstring_equalLit (id, "__declspec"))
-       {
-         int depth = 0;
-         bool useparens = FALSE;
-         bool usebraces = FALSE;
-         bool inquote = FALSE;
-         bool inescape = FALSE;
-         int ic;
-
-         while ((ic = input ()) != EOF)
-           {
-                             
-             if (inescape)
-               {
-                 inescape = FALSE;
-               }
-             else if (ic == '\\')
-               {
-                 inescape = TRUE;
-               }
-             else if (ic == '\"')
-               {
-                 inquote = !inquote;
-               }
-             else if (!inquote)
-               {
-                 if (ic == '(')
-                   {
-                     if (!useparens)
-                       {
-                         if (!usebraces)
-                           {
-                             useparens = TRUE;
-                           }
-                       }
-
-                     if (useparens)
-                       {
-                         depth++;
-                       }
-                   }
-                 else if (ic == '{')
-                   {
-                     if (!usebraces)
-                       {
-                         if (!useparens)
-                           {
-                             usebraces = TRUE;
-                           }
-                       }
-
-                     if (usebraces)
-                       {
-                         depth++;
-                       }
-                   }
-                 else if (ic == ')' && useparens)
-                   {
-                     depth--;
-                     if (depth == 0) break;
-                   }
-                 else if (ic == '}' && usebraces)
-                   {
-                     depth--;
-                     if (depth == 0) break;
-                   }
-                 else if (ic == '}' 
-                          && !usebraces && !useparens
-                          && cstring_equalLit (id, "__asm"))
-                   {
-                     /*
-                     ** We need this because some MS VC++ include files
-                     ** have __asm mov ... }
-                     ** Its a kludge, but otherwise would need to parse
-                     ** the asm code!
-                     */ 
-                     return TRBRACE;
-                   }
-               }
-
-             if (ic == '\n')
-               {
-                 context_incLineno ();
-
-                 if (cstring_equalLit (id, "__asm")
-                     && !useparens && !usebraces)
-                   {
-                     break;
-                   }
-               }
-           }
-         
-         llassert ((useparens && ic == ')')
-                   || (usebraces && ic == '}')
-                   || (!useparens && !usebraces));
-
-         return BADTOK;
-       }
-      else if (cstring_equalLit (id, "inline")
-              || cstring_equalLit (id, "__inline")
-              || cstring_equalLit (id, "_inline")
-              || cstring_equalLit (id, "__inline__"))
-       {
-         tok = QINLINE;
-       }
-      
-      if (tok != BADTOK)
-       {
-         RETURN_TOK (tok);
-       }
-    }
-
-  le = usymtab_lookupSafe (id);
-
-  /*@-dependenttrans@*/
-  
-  if (uentry_isIter (le))
-    {
-      /*@i32@*/ yylval.entry = le;
-      return (ITER_NAME);
-    }
-  else if (uentry_isEndIter (le))
-    {
-      /*@i32@*/ yylval.entry = le;
-      return (ITER_ENDNAME);
-    }
-  else if (uentry_isUndefined (le))
-    {
-      yylval.cname = id;
-
-      /* avoid parse errors for certain system built ins */
-
-      if (g_expectingTypeName && (cstring_firstChar (id) == '_')
-         && (cstring_secondChar (id) == '_'))
-       {
-         return (TYPE_NAME_OR_ID);
-       }
-
-      return (NEW_IDENTIFIER);
-    }
-  else if (!uentry_isDeclared (le) && !uentry_isCodeDefined (le))
-    {
-      if (uentry_isDatatype (le))
-       {
-         yylval.cname = id;
-         return (NEW_IDENTIFIER);
-       }
-      else
-       {
-         /*@i32@*/ yylval.entry = le;            
-         return (IDENTIFIER); 
-       }
-    }
-  else if (uentry_isDatatype (le))
-    {
-      if (!g_expectingTypeName)
-       {
-         yylval.cname = id;
-
-         return (NEW_IDENTIFIER);
-       }
-      else
-       {
-         yylval.ctyp = uentry_getAbstractType (le);
-         
-         uentry_setUsed (le, g_currentloc);
-         return (TYPE_NAME);
-       }
-    }
-  else
-    {
-      /*@i32@*/ yylval.entry = le;            
-      return (IDENTIFIER); 
-    }
-
-  /*@=dependenttrans@*/
-}
-
-static bool processHashIdentifier (/*@only@*/ cstring id)
-{
-  if (context_inMacro () || context_inIterDef () ||
-      context_inIterEnd ())
-    {
-      uentry le;
-      
-      context_clearJustPopped ();
-
-      lastidprocessed = id; 
-      le = usymtab_lookupSafe (id);
-
-      if (uentry_isParam (le) || uentry_isRefParam (le))
-       {
-         return TRUE;
-       }
-      else
-       {
-         return FALSE;
-       }
-    }
-  else
-    {
-      cstring_free (id);
-      return FALSE;
-    }
-}
-
-
-static /*@only@*/ exprNode processString ()
-{
-  exprNode res;
-  fileloc loc;
-  char *nl = strchr (yytext, '\n');
-  cstring ns = cstring_fromCharsNew (yytext);
-
-  if (nl == NULL)
-    {
-      loc = fileloc_copy (g_currentloc);
-      addColumn (cstring_length (ns));
-    }
-  else
-    {
-      char *lastnl = nl;
-
-      loc = fileloc_copy (g_currentloc);
-
-      context_incLineno ();
-      
-      while ((nl = strchr ((nl + 1), '\n')) != NULL)
-       {
-         context_incLineno ();
-         lastnl = nl;
-       }
-    }
-
-    
-  res = exprNode_stringLiteral (ns, loc);
-  return (res);
-}
-
-static 
-char processChar ()
-{
-  char fchar;
-  char next;
-
-  llassert (*yytext != '\0');
-  fchar = *(yytext + 1);
-  if (fchar != '\\') return fchar;
-  
-  next = *(yytext + 2);
-  
-  switch (next)
-    {
-    case 'n': return '\n';
-    case 't': return '\t';
-    case '\"': return '\"';
-    case '\'': return '\'';
-    case '\\': return '\\';
-    default: return '\0';
-    }
-}
-
-static
-double processFloat ()
-{
-  double ret = atof (yytext);
-
-    return (ret);
-}
-
-static
-long processHex ()
-{
-  int index = 2;
-  long val = 0;
-
-  llassert (yytext[0] == '0'
-           && (yytext[1] == 'X' || yytext[1] == 'x'));
-
-  while (yytext[index] != '\0') {
-    int tval;
-    char c = yytext[index];
-
-    if (c >= '0' && c <= '9') {
-      tval = (int) c - (int) '0';
-    } else if (c >= 'A' && c <= 'F') {
-      tval = (int) c - (int) 'A' + 10;
-    } else if (c >= 'a' && c <= 'f') {
-      tval = (int) c - (int) 'a' + 10;
-    } else if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {
-      index++;
-      while (yytext[index] != '\0') {
-       if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {
-         ;
-       } else {
-         voptgenerror
-           (FLG_SYNTAX, 
-            message ("Invalid character (%c) following specifier in hex constant: %s",
-                     c, cstring_fromChars (yytext)),
-            g_currentloc);
-       }
-       index++;
-      }
-
-      break;
-    } else {
-      voptgenerror
-       (FLG_SYNTAX, 
-        message ("Invalid character (%c) in hex constant: %s",
-                 c, cstring_fromChars (yytext)),
-        g_currentloc);
-      break;
-    }
-
-    val = (val * 16) + tval;
-    index++;
-  }
-
-  DPRINTF (("Hex constant: %s = %ld", yytext, val));
-  return val;
-}
-
-static
-long processOctal ()
-{
-  int index = 1;
-  long val = 0;
-
-  llassert (yytext[0] == '0' && yytext[1] != 'X' && yytext[1] != 'x');
-    
-  while (yytext[index] != '\0') {
-    int tval;
-    char c = yytext[index];
-    
-    if (c >= '0' && c <= '7') {
-      tval = (int) c - (int) '0';
-    } else {
-      voptgenerror
-       (FLG_SYNTAX, 
-        message ("Invalid character (%c) in octal constant: %s",
-                 c, cstring_fromChars (yytext)),
-        g_currentloc);
-      break;
-    }
-
-    val = (val * 8) + tval;
-    index++;
-  }
-
-  DPRINTF (("Octal constant: %s = %ld", yytext, val));
-  return val;
-}
-
-static
-long processDec ()
-{
-  return (atol (yytext));
-}
-
-static int
-processSpec (int tok)
-{
-  size_t length = strlen (yytext);
-  
-  if (inSpecPart)
-    {
-      setTokLengthT (length);
-      RETURN_TOK (tok);
-    }
-  else
-    {
-      
-      context_saveLocation ();
-      setTokLengthT (length);
-      return (processIdentifier (makeIdentifier (yytext)));
-    }
-}
-
-void cscanner_expectingMetaStateName ()
-{
-  llassert (!expectingMetaStateName);
-  llassert (context_inFunctionHeader ());
-  expectingMetaStateName = TRUE;
-}
-
-void cscanner_clearExpectingMetaStateName ()
-{
-  llassert (expectingMetaStateName);
-  expectingMetaStateName = FALSE;
-}
+/*;-*-C-*-; \r
+** Copyright (c) Massachusetts Institute of Technology 1994-1998.\r
+**          All Rights Reserved.\r
+**          Unpublished rights reserved under the copyright laws of\r
+**          the United States.\r
+**\r
+** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED\r
+** OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.\r
+**\r
+** This code is distributed freely and may be used freely under the \r
+** following conditions:\r
+**\r
+**     1. This notice may not be removed or altered.\r
+**\r
+**     2. Works derived from this code are not distributed for\r
+**        commercial gain without explicit permission from MIT \r
+**        (for permission contact lclint-request@sds.lcs.mit.edu).\r
+*/\r
+/*\r
+ * Modified by Herbert 08/19/97:\r
+ * - added #include for IBM's OS/2 compiler.\r
+ * - fixed weird bug with lookup of tmp files (OS/2 and MSDOS only).\r
+ */\r
+\r
+/*\r
+ * Modified by Mike Smith \r
+ * Corrected missing 'line' in scanf() calls in handleSpecial().\r
+ * Without this, I get an error when LCLint hits a '#line' directive\r
+ * in the pre-pre-processed source files. For safety, I have made these\r
+ * conditional on OS2 and MSDOS because I don't understand why noone else\r
+ * has seen this problem.\r
+ *\r
+ * Modified by Mike Smith, 4th June 1997\r
+ * Finally resolved the #line problem.  The scanf() calls have been fixed to\r
+ * allow the following #line forms:-\r
+ *\r
+ *        #line 123 "filename"\r
+ *        #line 123\r
+ *        # 123 "filename"\r
+ *        # 123\r
+ *\r
+ * The last two are generated by the GNU pre-processor, apparently\r
+ */\r
+\r
+Digit                  [0-9]\r
+Letter                 [a-zA-Z_$]\r
+H                      [a-fA-F0-9]\r
+E                      [Ee][+-]?{Digit}+\r
+U                       (u|U)\r
+L                       (l|L)\r
+FS                     (f|F|l|L)\r
+IS                     (u|U|l|L)*\r
+ULSuffix                ({U}{L}|{L}{U})\r
+\r
+%{\r
+/*\r
+** based on original C lexer by Nate Osgood\r
+**    from hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993\r
+**\r
+*/\r
+\r
+# include "lclintMacros.nf"\r
+# if defined(OS2) && defined(__IBMC__)\r
+   /* needed for isatty()... */\r
+# include <io.h>\r
+# else\r
+# include <unistd.h>\r
+# endif\r
+\r
+# include "basic.h"\r
+\r
+# include "cgrammar.h"\r
+# include "cgrammar_tokens.h"\r
+\r
+# include "fileIdList.h"\r
+# include "portab.h"\r
+\r
+static bool lastWasString = FALSE;\r
+static char savechar = '\0';\r
+\r
+/*@notfunction@*/\r
+# define yyinput() (incColumn (), getc (yyin))\r
+\r
+static /*@owned@*/ cstring lastidprocessed = cstring_undefined;\r
+static int lminput (void);\r
+static int tokLength = 0;\r
+static bool inSpecPart = FALSE;\r
+static bool continueLine = FALSE;\r
+\r
+static int ninput (void);\r
+static char processChar (void);\r
+static double processFloat (void);\r
+static /*@only@*/ exprNode processString (void);\r
+static long processDec (void);\r
+static long processHex (void);\r
+static long processOctal (void);\r
+static int processIdentifier (/*@only@*/ cstring)\r
+   /*@globals undef lastidprocessed@*/ ;\r
+static bool processHashIdentifier (/*@only@*/ cstring)\r
+   /*@globals undef lastidprocessed@*/ ;\r
+\r
+static int processSpec (int);\r
+static bool handleSpecial (char *);\r
+static int handleLlSpecial (void);\r
+static void handleMacro (void);\r
+static bool processMacro (void);\r
+static /*@only@*/ cstring makeIdentifier (char *);\r
+\r
+/* yes, this is exported! */\r
+bool g_expectingTypeName = TRUE; /* beginning of file can be type name! */\r
+\r
+static bool expectingMetaStateName = FALSE;\r
+\r
+static int returnInt (ctype, long);\r
+static int returnFloat (ctype, double);\r
+static int returnChar (char);\r
+static void setTokLength (int) /*@modifies g_currentloc@*/ ;\r
+static void setTokLengthT (size_t) /*@modifies g_currentloc@*/ ;\r
+\r
+static void advanceLine (void)\r
+{\r
+  tokLength = 0;\r
+  beginLine ();\r
+}\r
+    \r
+/*@-allmacros@*/\r
+# define RETURN_INT(c,i) \\r
+  do { lastWasString = FALSE; \\r
+       return (returnInt (c, i)); } while (FALSE)\r
+\r
+# define RETURN_FLOAT(c,f) \\r
+  do { lastWasString = FALSE; \\r
+       return (returnFloat (c, f)); \\r
+       } while (FALSE)\r
+\r
+# define RETURN_CHAR(c) \\r
+  do { lastWasString = FALSE; \\r
+       return (returnChar (c)); \\r
+     } while (FALSE)\r
+\r
+# define RETURN_TOK(t) \\r
+  do { yylval.tok = lltok_create (t, fileloc_decColumn (g_currentloc, tokLength)); \\r
+       tokLength = 0; \\r
+       lastWasString = FALSE; \\r
+       return (t); } while (FALSE)\r
+\r
+# define RETURN_TYPE(t, ct) \\r
+  do { yylval.ctyp = ct; tokLength = 0; return (t); } while (FALSE)\r
+\r
+/* don't fileloc_decColumn (g_currentloc, tokLength));  \r
+   the string could have \n's in it!\r
+*/\r
+\r
+# define RETURN_STRING(c) \\r
+ do { yylval.expr = exprNode_stringLiteral (c, fileloc_decColumn (g_currentloc, tokLength)); \\r
+      tokLength = 0; \\r
+      lastWasString = TRUE; \\r
+      return (CCONSTANT); } while (FALSE)\r
+\r
+# define RETURN_EXPR(e) \\r
+ do { yylval.expr = e; \\r
+      tokLength = 0; \\r
+      lastWasString = TRUE; \\r
+      return (CCONSTANT); } while (FALSE)\r
+\r
+/*@=allmacros@*/\r
+\r
+static void setTokLength (int len) \r
+{\r
+  addColumn (len);\r
+  tokLength = len;\r
+  DPRINTF (("Set tok length: %d", len));\r
+}\r
+\r
+static void setTokLengthT (size_t len)\r
+{\r
+  setTokLength (size_toInt (len));\r
+}\r
+\r
+# include "flex.head"\r
+\r
+/*@-unrecog@*/ /*@i5343@*/\r
+\r
+%}\r
+\r
+%%\r
+\r
+"/*"           { llfatalbug (cstring_makeLiteral ("Comment in pre-processor output")); }\r
+\r
+"#"{Letter}({Letter}|{Digit})*  { \r
+                 context_saveLocation (); \r
+                 setTokLength (longUnsigned_toInt (mstring_length (yytext))); \r
+\r
+                 if (processHashIdentifier (makeIdentifier (yytext + 1)))\r
+                   {\r
+                    if (lastWasString)\r
+                      {\r
+                        /* was nothing! */ /*@i32@*/\r
+                        RETURN_STRING (cstring_makeLiteral ("\"\""));\r
+                      }\r
+                    else\r
+                      {\r
+                        RETURN_STRING (cstring_makeLiteral ("\"\""));\r
+                      }\r
+                  }\r
+                 else\r
+                   { \r
+                    if (handleSpecial (yytext)) \r
+                       { \r
+                        setTokLength (1); \r
+                        RETURN_TOK (0); \r
+                      }\r
+                  }\r
+                } \r
+"#"             { if (handleSpecial (yytext)) \r
+                    { \r
+                       setTokLength (1); RETURN_TOK (0); \r
+                     }\r
+                }\r
+"..."           { setTokLength (3); RETURN_TOK (CTOK_ELIPSIS); }\r
+"break"                { setTokLength (5); RETURN_TOK (BREAK); }\r
+"case"         { setTokLength (4); RETURN_TOK (CASE); }\r
+"continue"     { setTokLength (8); RETURN_TOK (CONTINUE); }\r
+"default"      { setTokLength (7); RETURN_TOK (DEFAULT); }\r
+"do"           { setTokLength (2); RETURN_TOK (DO); }\r
+"else"         { setTokLength (4); RETURN_TOK (CELSE); }\r
+"for"          { setTokLength (3); RETURN_TOK (CFOR); }\r
+"goto"         { setTokLength (4); RETURN_TOK (GOTO); }\r
+"if"           { setTokLength (2); RETURN_TOK (CIF); }\r
+"return"       { setTokLength (6); RETURN_TOK (RETURN); }\r
+"sizeof"       { setTokLength (6); RETURN_TOK (CSIZEOF); }\r
+"offsetof"     { setTokLength (8); RETURN_TOK (COFFSETOF); }\r
+"switch"       { setTokLength (6); RETURN_TOK (SWITCH); }\r
+"while"                { setTokLength (5); RETURN_TOK (WHILE); }\r
+"va_arg"        { setTokLength (6); RETURN_TOK (VA_ARG); }   \r
+"va_dcl"        { setTokLength (6); RETURN_TOK (VA_DCL); }   \r
+"inline"        { \r
+                  /* gcc extension...this might not be appropriate */\r
+                  setTokLength (6); RETURN_TOK (QINLINE); }\r
+\r
+"struct"        { setTokLength (6); RETURN_TOK (CSTRUCT); }  \r
+"typedef"       { setTokLength (7); RETURN_TOK (CTYPEDEF); }\r
+\r
+"union"         { setTokLength (5); RETURN_TOK (CUNION); }\r
+"enum"          { setTokLength (4); RETURN_TOK (CENUM); }\r
+\r
+"void"         { setTokLength (4); RETURN_TYPE (CVOID, ctype_void); }\r
+"int"          { setTokLength (3); RETURN_TYPE (CINT, ctype_int); }\r
+"double"       { setTokLength (6); RETURN_TYPE (CDOUBLE, ctype_double); }\r
+"char"         { setTokLength (4); RETURN_TYPE (CGCHAR, ctype_char); }\r
+"float"                { setTokLength (5); RETURN_TYPE (CGFLOAT, ctype_float); }\r
+\r
+"long"         { setTokLength (4); RETURN_TOK (QLONG); }\r
+"short"                { setTokLength (5); RETURN_TOK (QSHORT); }\r
+"unsigned"     { setTokLength (8); RETURN_TOK (QUNSIGNED); }\r
+"signed"       { setTokLength (6); RETURN_TOK (QSIGNED); }\r
+\r
+"volatile"     { setTokLength (8); RETURN_TOK (QVOLATILE); }\r
+"const"                { setTokLength (5); RETURN_TOK (QCONST); }\r
+\r
+                        /* some systems expect this! [gack!] */ \r
+"__const"      { setTokLength (7); RETURN_TOK (QCONST); }\r
+\r
+"extern"       { setTokLength (6); RETURN_TOK (QEXTERN); }\r
+"auto"         { setTokLength (4); RETURN_TOK (QAUTO); }\r
+"register"     { setTokLength (8); RETURN_TOK (QREGISTER); }\r
+"static"       { setTokLength (6); RETURN_TOK (QSTATIC); }\r
+\r
+\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }\r
+L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }\r
+"out"                   { return (processSpec (QOUT)); }\r
+"in"                    { return (processSpec (QIN)); }\r
+"partial"               { return (processSpec (QPARTIAL)); }\r
+"special"               { return (processSpec (QSPECIAL)); }\r
+"anytype"               { return (processSpec (QANYTYPE)); }\r
+"integraltype"          { return (processSpec (QINTEGRALTYPE)); }\r
+"unsignedintegraltype"  { return (processSpec (QUNSIGNEDINTEGRALTYPE)); }\r
+"signedintegraltype"    { return (processSpec (QSIGNEDINTEGRALTYPE)); }\r
+"keep"                  { return (processSpec (QKEEP)); }\r
+"null"                  { return (processSpec (QNULL)); } \r
+"notnull"               { return (processSpec (QNOTNULL)); } \r
+"isnull"                { return (processSpec (QISNULL)); } \r
+"truenull"              { return (processSpec (QTRUENULL)); } \r
+"falsenull"             { return (processSpec (QFALSENULL)); } \r
+"relnull"               { return (processSpec (QRELNULL)); }\r
+"reldef"                { return (processSpec (QRELDEF)); }\r
+"exposed"               { return (processSpec (QEXPOSED)); }\r
+"newref"                { return (processSpec (QNEWREF)); }\r
+"tempref"               { return (processSpec (QTEMPREF)); }\r
+"killref"               { return (processSpec (QKILLREF)); }\r
+"refcounted"            { return (processSpec (QREFCOUNTED)); }\r
+"checked"               { return (processSpec (QCHECKED)); }\r
+"checkmod"              { return (processSpec (QCHECKMOD)); }\r
+"checkedstrict"         { return (processSpec (QCHECKEDSTRICT)); }\r
+"unchecked"             { return (processSpec (QUNCHECKED)); }\r
+"only"                  { return (processSpec (QONLY)); }\r
+"owned"                 { return (processSpec (QOWNED)); }\r
+"observer"              { return (processSpec (QOBSERVER)); }\r
+"dependent"             { return (processSpec (QDEPENDENT)); }\r
+"unused"                { return (processSpec (QUNUSED)); }\r
+"external"              { return (processSpec (QEXTERNAL)); }\r
+"sef"                   { return (processSpec (QSEF)); }\r
+"shared"                { return (processSpec (QSHARED)); }\r
+"yield"                 { return (processSpec (QYIELD)); }\r
+"undef"                 { return (processSpec (QUNDEF)); }\r
+"killed"                { return (processSpec (QKILLED)); }\r
+"nullterminated"        { return (processSpec (QNULLTERMINATED));}\r
+"MaxSet"                { return (processSpec (QMAXSET));}\r
+"MaxRead"               { return (processSpec (QMAXREAD));}\r
+"maxSet"                { return (processSpec (QMAXSET));}\r
+"maxRead"               { return (processSpec (QMAXREAD));}\r
+\r
+{Letter}({Letter}|{Digit})* { int tok; \r
+                             context_saveLocation (); \r
+                             setTokLength (longUnsigned_toInt (mstring_length (yytext))); \r
+                             tok = processIdentifier (makeIdentifier (yytext)); \r
+                             if (tok != BADTOK)\r
+                               {\r
+                                 return (tok);\r
+                               }\r
+                           }\r
+0[xX]{H}+              { setTokLengthT (mstring_length (yytext)); \r
+                          RETURN_INT (ctype_int, processHex ());  /* evs 2000-05-17 was ctype_uint */\r
+                       }\r
+0[xX]{H}+{L}           { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_lint, processHex ()); }\r
+0[xX]{H}+{L}{L}                { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_llint, processHex ()); }\r
+0[xX]{H}+{U}           { setTokLengthT (mstring_length (yytext)); \r
+                          RETURN_INT (ctype_uint, processHex ()); }\r
+0[xX]{H}+{ULSuffix}     { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_ulint, processHex ()); }\r
+0[xX]{H}+{U}{L}{L}      { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_ullint, processHex ()); }\r
+0[xX]{H}+{L}{L}{U}      { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_ullint, processHex ()); }\r
+0{Digit}+              { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_int, processOctal ()); } \r
+0{Digit}+{U}           { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_uint, processOctal ()); } \r
+0{Digit}+{L}           { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_lint, processOctal ()); } \r
+0{Digit}+{L}{L}                { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_llint, processOctal ()); } \r
+0{Digit}+{ULSuffix}     { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_ulint, processOctal ()); } \r
+0{Digit}+{U}{L}{L}      { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_ullint, processOctal ()); } \r
+0{Digit}+{L}{L}{U}      { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_INT (ctype_ullint, processOctal ()); } \r
+{Digit}+              { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_INT (ctype_int, processDec ()); } \r
+{Digit}+{U}           { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_INT (ctype_uint, processDec ()); } \r
+{Digit}+{L}           { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_INT (ctype_lint, processDec ()); } \r
+{Digit}+{L}{L}        { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_INT (ctype_llint, processDec ()); } \r
+{Digit}+{ULSuffix}     { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_INT (ctype_ulint, processDec ()); } \r
+{Digit}+{U}{L}{L}      { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_INT (ctype_ullint, processDec ()); } \r
+{Digit}+{L}{L}{U}      { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_INT (ctype_ullint, processDec ()); } \r
+'(\\.|[^\\'])+'               { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_CHAR (processChar ()); }\r
+L'(\\.|[^\\'])+'       { setTokLengthT (mstring_length (yytext)); \r
+                         RETURN_CHAR (processChar ()); }\r
+{Digit}+{E}[fF]        { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_FLOAT (ctype_float, processFloat ()); }\r
+{Digit}+{E}[lL]        { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_FLOAT (ctype_ldouble, processFloat ()); }\r
+{Digit}+{E}            { setTokLengthT (mstring_length (yytext)); \r
+                        RETURN_FLOAT (ctype_double, processFloat ()); }\r
+\r
+{Digit}*"."{Digit}+({E})?[fF] { setTokLengthT (mstring_length (yytext)); \r
+                               RETURN_FLOAT (ctype_float, processFloat ()); }\r
+{Digit}*"."{Digit}+({E})?[lL] { setTokLengthT (mstring_length (yytext)); \r
+                               RETURN_FLOAT (ctype_ldouble, processFloat ()); }\r
+{Digit}*"."{Digit}+({E})?     { setTokLengthT (mstring_length (yytext)); \r
+                               RETURN_FLOAT (ctype_double, processFloat ()); }\r
+\r
+{Digit}+"."{Digit}*({E})?[fF]   { setTokLengthT (mstring_length (yytext)); \r
+                                 RETURN_FLOAT (ctype_float, processFloat ()); }\r
+{Digit}+"."{Digit}*({E})?[lL]   { setTokLengthT (mstring_length (yytext)); \r
+                                 RETURN_FLOAT (ctype_ldouble, processFloat ()); }\r
+{Digit}+"."{Digit}*({E})?       { setTokLengthT (mstring_length (yytext)); \r
+                                 RETURN_FLOAT (ctype_double, processFloat ()); }\r
+\r
+">>="          { setTokLength (3); RETURN_TOK (RIGHT_ASSIGN); }\r
+"<<="          { setTokLength (3); RETURN_TOK (LEFT_ASSIGN); }\r
+"+="           { setTokLength (2); RETURN_TOK (ADD_ASSIGN); }\r
+"-="           { setTokLength (2); RETURN_TOK (SUB_ASSIGN); }\r
+"*="           { setTokLength (2); RETURN_TOK (MUL_ASSIGN); }\r
+"/="           { setTokLength (2); RETURN_TOK (DIV_ASSIGN); }\r
+"%="           { setTokLength (2); RETURN_TOK (MOD_ASSIGN); }\r
+"&="           { setTokLength (2); RETURN_TOK (AND_ASSIGN); }\r
+"^="           { setTokLength (2); RETURN_TOK (XOR_ASSIGN); }\r
+"|="           { setTokLength (2); RETURN_TOK (OR_ASSIGN); }\r
+">>"           { setTokLength (2); RETURN_TOK (RIGHT_OP); }\r
+"<<"           { setTokLength (2); RETURN_TOK (LEFT_OP); }\r
+"++"           { setTokLength (2); RETURN_TOK (INC_OP); }\r
+"--"           { setTokLength (2); RETURN_TOK (DEC_OP); }\r
+"->"           { setTokLength (2); RETURN_TOK (ARROW_OP); }\r
+"&&"           { setTokLength (2); RETURN_TOK (AND_OP); }\r
+"||"           { setTokLength (2); RETURN_TOK (OR_OP); }\r
+"<="           { setTokLength (2); RETURN_TOK (LE_OP); }\r
+">="           { setTokLength (2); RETURN_TOK (GE_OP); }\r
+"=="           { setTokLength (2); RETURN_TOK (EQ_OP); }\r
+"!="           { setTokLength (2); RETURN_TOK (NE_OP); }\r
+";"            { setTokLength (1); RETURN_TOK (TSEMI); }\r
+"{"            { setTokLength (1); RETURN_TOK (TLBRACE); }\r
+"}"            { setTokLength (1); RETURN_TOK (TRBRACE); }\r
+","            { setTokLength (1); RETURN_TOK (TCOMMA); }\r
+":"            { setTokLength (1); RETURN_TOK (TCOLON); }\r
+"="            { setTokLength (1); RETURN_TOK (TASSIGN); }\r
+"("            { setTokLength (1); RETURN_TOK (TLPAREN); }\r
+")"            { setTokLength (1); RETURN_TOK (TRPAREN); }\r
+"["            { setTokLength (1); RETURN_TOK (TLSQBR); }\r
+"]"            { setTokLength (1); RETURN_TOK (TRSQBR); }\r
+"."            { setTokLength (1); RETURN_TOK (TDOT); }\r
+"&"            { setTokLength (1); RETURN_TOK (TAMPERSAND); }\r
+"!"            { setTokLength (1); RETURN_TOK (TEXCL); }\r
+\r
+\r
+"~"            { setTokLength (1); RETURN_TOK (TTILDE); }\r
+"-"            { setTokLength (1); RETURN_TOK (TMINUS); }\r
+"+"            { setTokLength (1); RETURN_TOK (TPLUS); }\r
+"*"            { setTokLength (1); RETURN_TOK (TMULT); }\r
+"/"            { setTokLength (1); RETURN_TOK (TDIV); }\r
+"%"            { setTokLength (1); RETURN_TOK (TPERCENT); }\r
+"<"            { setTokLength (1); RETURN_TOK (TLT); }\r
+">"            { setTokLength (1); RETURN_TOK (TGT); }\r
+"^"            { setTokLength (1); RETURN_TOK (TCIRC); }\r
+"|"            { setTokLength (1); RETURN_TOK (TBAR); }\r
+"?"            { setTokLength (1); RETURN_TOK (TQUEST); }\r
+\r
+\r
+"/\\"          { setTokLength (1); RETURN_TOK (TCAND); }\r
+\r
+\r
+[ \t\v\f]      { incColumn (); }\r
+\n              { context_incLineno ();\r
+                  if (tokLength != 0) { \r
+                   tokLength = 0; \r
+                   /* No error to report \r
+                   voptgenerror\r
+                     (FLG_SYNTAX, \r
+                      message ("Likely parse error: token spans multiple lines."),\r
+                      g_currentloc);\r
+                   */\r
+                 }\r
+                 \r
+                 if (continueLine)\r
+                   {\r
+                     continueLine = FALSE;\r
+                   }\r
+                 else \r
+                  {\r
+                    if (context_inMacro ())\r
+                      {\r
+                        /* Don't use RETURN_TOK */\r
+                        yylval.tok = lltok_create (TENDMACRO, g_currentloc);\r
+                        lastWasString = FALSE;\r
+                        return (TENDMACRO);\r
+                      }  \r
+                  }\r
+               }\r
+"@@MR@@"        { setTokLength (6); \r
+                 \r
+                 if (processMacro ()) {\r
+                   if (context_inIterDef ()) \r
+                     { \r
+                       RETURN_TOK (LLMACROITER); \r
+                     }\r
+                   if (context_inIterEnd ())\r
+                     {\r
+                       RETURN_TOK (LLMACROEND); \r
+                     }\r
+                   if (context_inMacro ())\r
+                     {\r
+                       RETURN_TOK (LLMACRO); \r
+                     }\r
+                 }\r
+               }\r
+"@QLMR"         { if (context_inHeader () || context_inFunction ())\r
+                   { \r
+                     handleMacro ();\r
+                   }\r
+                  else\r
+                   {\r
+                     int nspchar = ninput ();\r
+                     int nspaces;\r
+\r
+                     /* \r
+                     ** This is a hack to get the column number correct.\r
+                     */\r
+\r
+                     llassert (nspchar >= '0' && nspchar <= '9');\r
+                     \r
+                     nspaces = nspchar - '0';\r
+\r
+                     setTokLength (5 + nspaces); \r
+                     \r
+                     if (processMacro ()) \r
+                       {\r
+                         if (context_inIterDef ()) \r
+                           {\r
+                             RETURN_TOK (LLMACROITER); \r
+                           }\r
+                         if (context_inIterEnd ())\r
+                           {\r
+                             RETURN_TOK (LLMACROEND); \r
+                           }\r
+                         if (context_inMacro ())\r
+                           { \r
+                             RETURN_TOK (LLMACRO); \r
+                           }\r
+                       }\r
+                   }\r
+               }\r
+"@.CT"          { setTokLength (4); lldiagmsg (ctype_unparseTable ()); }\r
+"@.FA"          { setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); }\r
+"@.F"           { setTokLength (3); \r
+                 lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc)));\r
+               }\r
+"@.L"           { setTokLength (3); usymtab_printLocal (); }\r
+"@.A"           { setTokLength (3); lldiagmsg (usymtab_unparseAliases ()); }\r
+"@.C"           { setTokLength (3); lldiagmsg (context_unparse ()); }\r
+"@.W"           { setTokLength (3); lldiagmsg (context_unparseClauses ()); }\r
+"@.G"           { setTokLength (3); usymtab_printGuards (); }\r
+"@.S"           { setTokLength (3); usymtab_printOut (); }\r
+"@.X"           { setTokLength (3); usymtab_printAll (); }\r
+"@.Z"           { setTokLength (3); usymtab_printComplete (); }\r
+"@.T"           { setTokLength (3); usymtab_printTypes (); }\r
+"@.K"           { setTokLength (3); lldiagmsg (usymtab_unparseStack ()); }\r
+"@.M"           { setTokLength (3); \r
+                 lldiagmsg (message ("Can modify: %q", \r
+                                 sRefSet_unparse (context_modList ()))); \r
+               }\r
+"%{"            { /* BEFORE_COMMENT_MARKER */\r
+                  int tok; \r
+                 incColumn (); incColumn ();\r
+                 tok = handleLlSpecial (); \r
+\r
+                 if (tok != BADTOK)\r
+                   {\r
+                     if (tok == CANNOTATION) {\r
+                       return (tok);\r
+                     } else {\r
+                       /* Beware - this bashes yylval! */\r
+                       RETURN_TOK (tok); \r
+                     }\r
+                   }\r
+               }\r
+"%}"            { /* AFTER_COMMENT_MARKER */ \r
+                  setTokLength (2);\r
+                 inSpecPart = FALSE;\r
+                 RETURN_TOK (QENDMACRO); }\r
+"\\"            { incColumn (); continueLine = TRUE; }\r
+.              { incColumn (); \r
+                  if ((int) *yytext == 13 ) {\r
+                    ;\r
+                  } else {\r
+                   voptgenerror\r
+                     (FLG_SYNTAX, \r
+                      message ("Invalid character (ascii: %d), skipping character",\r
+                               (int)(*yytext)),\r
+                      g_currentloc);\r
+                 }\r
+               }\r
+%%\r
+\r
+struct skeyword\r
+{\r
+  /*@null@*/ /*@observer@*/ char *name;\r
+  int token;\r
+} ;\r
+\r
+/*\r
+** These tokens are followed by syntax that is parsed by the \r
+** grammar proper.\r
+*/\r
+\r
+struct skeyword s_parsetable[] = {\r
+  { "modifies", QMODIFIES } ,\r
+  { "globals", QGLOBALS } ,\r
+  { "alt", QALT } ,\r
+  { "warn", QWARN } ,\r
+  { "constant", QCONSTANT } ,\r
+  { "function", QFUNCTION } ,\r
+  { "iter", QITER } ,\r
+  { "defines", QDEFINES } ,\r
+  { "uses", QUSES } ,\r
+  { "allocates", QALLOCATES } ,\r
+  { "sets", QSETS } ,\r
+  { "releases", QRELEASES } ,\r
+  { "pre", QPRECLAUSE } ,\r
+  { "post", QPOSTCLAUSE } ,\r
+  { "setBufferSize", QSETBUFFERSIZE},\r
+  { "setStringLength", QSETSTRINGLENGTH},\r
+  { "testinRange", QTESTINRANGE},\r
+  { "requires", QPRECLAUSE } ,\r
+  { "ensures", QPOSTCLAUSE } ,\r
+  { NULL, BADTOK } \r
+} ;\r
+\r
+/*\r
+** These tokens are either stand-alone tokens, or followed by \r
+** token-specific text.\r
+*/\r
+\r
+struct skeyword s_keytable[] = {\r
+  { "anytype", QANYTYPE } ,\r
+  { "integraltype", QINTEGRALTYPE } ,\r
+  { "unsignedintegraltype", QUNSIGNEDINTEGRALTYPE } ,\r
+  { "signedintegraltype", QSIGNEDINTEGRALTYPE } ,\r
+  { "out", QOUT } ,\r
+  { "in", QIN } ,\r
+  { "only", QONLY } , \r
+  { "owned", QOWNED } ,\r
+  { "dependent", QDEPENDENT } ,\r
+  { "partial", QPARTIAL } ,\r
+  { "special", QSPECIAL } ,\r
+  { "truenull", QTRUENULL } ,\r
+  { "falsenull", QFALSENULL } ,\r
+  { "keep", QKEEP } ,\r
+  { "kept", QKEPT } ,\r
+  { "notnull", QNOTNULL } ,\r
+  { "abstract", QABSTRACT } ,\r
+  { "concrete", QCONCRETE } ,\r
+  { "mutable", QMUTABLE } ,\r
+  { "immutable", QIMMUTABLE } ,\r
+  { "unused", QUNUSED } ,\r
+  { "external", QEXTERNAL } ,\r
+  { "sef", QSEF } ,\r
+  { "unique", QUNIQUE } ,\r
+  { "returned", QRETURNED } ,\r
+  { "exposed", QEXPOSED } ,\r
+  { "refcounted", QREFCOUNTED } ,\r
+  { "refs", QREFS } ,\r
+  { "newref", QNEWREF } ,\r
+  { "tempref", QTEMPREF } ,\r
+  { "killref", QKILLREF } ,\r
+  { "null", QNULL } ,\r
+  { "relnull", QRELNULL } ,\r
+  { "nullterminated", QNULLTERMINATED }, \r
+  { "setBufferSize", QSETBUFFERSIZE },\r
+  { "testInRange", QTESTINRANGE},\r
+  { "MaxSet", QMAXSET},\r
+  { "MaxRead", QMAXREAD},\r
+  { "reldef", QRELDEF } ,\r
+  { "observer", QOBSERVER } ,\r
+  { "exits", QEXITS } ,\r
+  { "mayexit", QMAYEXIT } ,\r
+  { "trueexit", QTRUEEXIT } ,\r
+  { "falseexit", QFALSEEXIT } ,\r
+  { "neverexit", QNEVEREXIT } ,\r
+  { "temp", QTEMP } ,\r
+  { "shared", QSHARED } ,\r
+  { "ref", QREF } ,\r
+  { "unchecked", QUNCHECKED } ,\r
+  { "checked", QCHECKED } ,\r
+  { "checkmod", QCHECKMOD } ,\r
+  { "checkedstrict", QCHECKEDSTRICT } ,\r
+  { "innercontinue", QINNERCONTINUE } ,\r
+  { "innerbreak", QINNERBREAK } ,\r
+  { "loopbreak", QLOOPBREAK } ,\r
+  { "switchbreak", QSWITCHBREAK } ,\r
+  { "safebreak", QSAFEBREAK } , \r
+  { "fallthrough", QFALLTHROUGH } ,\r
+  { "l_fallthrou", QLINTFALLTHROUGH } , \r
+  { "l_fallth", QLINTFALLTHRU } ,\r
+  { "notreached", QNOTREACHED } ,\r
+  { "l_notreach", QLINTNOTREACHED } ,\r
+  { "printflike", QPRINTFLIKE } ,\r
+  { "l_printfli", QLINTPRINTFLIKE } ,\r
+  { "scanflike", QSCANFLIKE } ,\r
+  { "messagelike", QMESSAGELIKE } ,\r
+  { "l_argsus", QARGSUSED } ,\r
+  { NULL, BADTOK } \r
+} ;\r
+\r
+/*\r
+** would be better if these weren't hard coded...\r
+*/\r
+\r
+static bool isArtificial (cstring s)\r
+{\r
+  return (cstring_equalLit (s, "modifies") \r
+         || cstring_equalLit (s, "globals") \r
+         || cstring_equalLit (s, "warn")\r
+         || cstring_equalLit (s, "alt"));\r
+}\r
+\r
+void swallowMacro (void)\r
+{\r
+  int i;\r
+  bool skipnext = FALSE;\r
+\r
+  while ((i = lminput ()) != EOF)\r
+    {\r
+      char c = (char) i;\r
+      \r
+      \r
+      if (c == '\\')\r
+       {\r
+         skipnext = TRUE;\r
+       }\r
+      else if (c == '\n')\r
+       {\r
+         if (skipnext)\r
+           {\r
+             skipnext = FALSE;\r
+           }\r
+         else\r
+           {\r
+             reader_checkUngetc (i, yyin);\r
+             return;\r
+           }\r
+       }\r
+    }\r
+\r
+  if (i != EOF)\r
+    {\r
+      reader_checkUngetc (i, yyin);\r
+    }\r
+}\r
+\r
+static int commentMarkerToken (cstring s)\r
+{\r
+  int i = 0;\r
+  \r
+  while (s_parsetable[i].name != NULL) \r
+    {\r
+      DPRINTF (("Try :%s:%s:", s, s_parsetable[i].name));\r
+\r
+      if (cstring_equalLit (s, s_parsetable[i].name))\r
+       {\r
+         return s_parsetable[i].token;\r
+       }\r
+\r
+      i++;\r
+    }\r
+\r
+  return BADTOK;\r
+}\r
+\r
+static int tokenMacroCode (cstring s)\r
+{\r
+  int i = 0;\r
+  \r
+  while (s_keytable[i].name != NULL) \r
+    {\r
+      if (cstring_equalLit (s, s_keytable[i].name)) \r
+       {\r
+         if (s_keytable[i].token == QLINTFALLTHROUGH) \r
+           {\r
+             voptgenerror\r
+               (FLG_WARNLINTCOMMENTS,\r
+                cstring_makeLiteral\r
+                ("Traditional lint comment /*FALLTHROUGH*/ used.  "\r
+                 "This is interpreted by "\r
+                 "LCLint in the same way as most Unix lints, but it is "\r
+                 "preferable to replace it with the /*@fallthrough@*/ "\r
+                 "semantic comment"),\r
+                g_currentloc);\r
+             return QFALLTHROUGH;            \r
+           }\r
+         else if (s_keytable[i].token == QLINTFALLTHRU)\r
+           {\r
+             voptgenerror \r
+               (FLG_WARNLINTCOMMENTS,\r
+                cstring_makeLiteral\r
+                ("Traditional lint comment /*FALLTHRU*/ used.  "\r
+                 "This is interpreted by "\r
+                 "LCLint in the same way as most Unix lints, but it is "\r
+                 "preferable to replace it with the /*@fallthrough@*/ "\r
+                 "semantic comment"),\r
+                g_currentloc);\r
+             return QFALLTHROUGH;\r
+           }\r
+         else if (s_keytable[i].token == QLINTNOTREACHED)\r
+           {\r
+             voptgenerror \r
+               (FLG_WARNLINTCOMMENTS,\r
+                cstring_makeLiteral\r
+                ("Traditional lint comment /*NOTREACHED*/ used.  "\r
+                 "This is interpreted by "\r
+                 "LCLint in the same way as most Unix lints, but it is "\r
+                 "preferable to replace it with the /*@notreached@*/ "\r
+                 "semantic comment."),\r
+                g_currentloc);\r
+             \r
+             return QNOTREACHED;\r
+           }\r
+         else if (s_keytable[i].token == QPRINTFLIKE)\r
+           {\r
+             setSpecialFunction (qual_createPrintfLike ());\r
+             return SKIPTOK;\r
+           }\r
+         else if (s_keytable[i].token == QLINTPRINTFLIKE)\r
+           {         \r
+             voptgenerror \r
+               (FLG_WARNLINTCOMMENTS,\r
+                cstring_makeLiteral\r
+                ("Traditional lint comment /*PRINTFLIKE*/ used.  "\r
+                 "This is interpreted by "\r
+                 "LCLint in the same way as most Unix lints, but it is "\r
+                 "preferable to replace it with either /*@printflike@*/, "\r
+                 "/*@scanflike@*/ or /*@messagelike@*/."),\r
+                g_currentloc);\r
+             \r
+             setSpecialFunction (qual_createPrintfLike ());\r
+             return SKIPTOK;\r
+           }\r
+         else if (s_keytable[i].token == QSCANFLIKE)\r
+           {\r
+             setSpecialFunction (qual_createScanfLike ());\r
+             return SKIPTOK;\r
+           }\r
+         else if (s_keytable[i].token == QMESSAGELIKE)\r
+           {\r
+             setSpecialFunction (qual_createMessageLike ());\r
+             return SKIPTOK;\r
+           }\r
+         else if (s_keytable[i].token == QARGSUSED)\r
+           {\r
+             voptgenerror\r
+               (FLG_WARNLINTCOMMENTS,\r
+                cstring_makeLiteral\r
+                ("Traditional lint comment /*ARGSUSED*/ used.  "\r
+                 "This is interpreted by "\r
+                 "LCLint in the same way as most Unix lints, but it is "\r
+                 "preferable to use /*@unused@*/ annotations on "\r
+                 "the unused parameters."),\r
+                g_currentloc);\r
+             \r
+             setArgsUsed ();\r
+             return SKIPTOK;\r
+           }\r
+         \r
+         return s_keytable[i].token;\r
+       }\r
+      \r
+      i++;\r
+    }\r
+  \r
+  return BADTOK;\r
+}\r
+\r
+static int lminput ()\r
+{\r
+  if (savechar == '\0')\r
+    {\r
+      incColumn ();\r
+      return (input ());\r
+    }\r
+  else\r
+    {\r
+      int save = (int) savechar;\r
+      savechar = '\0';\r
+      return save;\r
+    }\r
+}\r
+\r
+static void lmsavechar (char c)\r
+{\r
+  if (savechar == '\0') savechar = c;\r
+  else\r
+    {\r
+      llbuglit ("lmsavechar: override");\r
+    }\r
+}\r
+\r
+static int returnFloat (ctype ct, double f)\r
+{\r
+  yylval.expr = exprNode_floatLiteral (f, ct, cstring_fromChars (yytext), \r
+                                      fileloc_decColumn (g_currentloc, tokLength));\r
+  tokLength = 0; \r
+  return (CCONSTANT);\r
+}\r
+\r
+static int returnInt (ctype ct, long i)\r
+{\r
+  ctype c = ct;\r
+\r
+  if (ctype_equal (ct, ctype_int))\r
+    {\r
+      if (i == 0)\r
+       {\r
+         c = context_typeofZero ();\r
+       }\r
+      else if (i == 1)\r
+       {\r
+         c = context_typeofOne ();\r
+       }\r
+    }\r
+  \r
+  yylval.expr = exprNode_numLiteral (c, cstring_fromChars (yytext), \r
+                                    fileloc_decColumn (g_currentloc, tokLength), i);   \r
+  tokLength = 0; \r
+  return (CCONSTANT);\r
+}\r
+\r
+static int returnChar (char c)\r
+{\r
+  yylval.expr = exprNode_charLiteral (c, cstring_fromChars (yytext), \r
+                                     fileloc_decColumn (g_currentloc, tokLength));\r
+  tokLength = 0; \r
+  return (CCONSTANT);\r
+}\r
+\r
+static int ninput ()  \r
+{\r
+  int c = lminput ();\r
+\r
+  if (c != EOF && ((char)c == '\n'))\r
+    {\r
+      context_incLineno ();\r
+    }\r
+\r
+  return c;\r
+}\r
+\r
+static char macro_nextChar ()\r
+{\r
+  static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE;\r
+  int ic;\r
+  char c;\r
+\r
+  ic = lminput ();\r
+  c = char_fromInt (ic);\r
+  \r
+  if (!in_quote && !in_char && (c == '\\' || c == BEFORE_COMMENT_MARKER[0]))\r
+    {\r
+      if (c == '\\')\r
+       {\r
+         while ((c = char_fromInt (lminput ())) != '\0' && c != '\n')\r
+           {\r
+             ; /* skip to newline */\r
+           }\r
+         \r
+         context_incLineno ();\r
+         \r
+         if (c != '\0')\r
+           {\r
+             return macro_nextChar ();\r
+           }\r
+         else \r
+           {\r
+             return c;\r
+           }\r
+       }\r
+      else /* if (c == '@') */\r
+       {\r
+         llassert (FALSE); /*@i23@*/\r
+         if (handleLlSpecial () != BADTOK)\r
+           {\r
+             llerrorlit (FLG_SYNTAX, "Macro cannot use special syntax");\r
+           }\r
+\r
+         return macro_nextChar ();\r
+       }\r
+    }\r
+  else if (!in_escape && c == '\"')\r
+    {\r
+      in_quote = !in_quote;\r
+    }\r
+  else if (!in_escape && c == '\'')\r
+    {\r
+      in_char = !in_char;\r
+    }\r
+  else if ((in_quote || in_char) && c == '\\')\r
+    {\r
+      in_escape = !in_escape;\r
+    }\r
+  else if ((in_quote || in_char) && in_escape)\r
+    {\r
+      in_escape = FALSE;\r
+    }\r
+  else if (!in_quote && c == '/')\r
+    {\r
+      char c2;\r
+      \r
+      if ((c2 = char_fromInt (lminput ())) == '*')\r
+       {\r
+         while (c2 != '\0')\r
+           {\r
+             while ((c2 = char_fromInt (lminput ())) != '\0'\r
+                    && c2 != '\n' && c2 != '*')\r
+               {\r
+                 ;\r
+               }\r
+             \r
+             if (c2 == '*')\r
+               {\r
+                 while ((c2 = char_fromInt (lminput ())) != '\0' \r
+                        && c2 == '*')\r
+                   {\r
+                     ;\r
+                   }\r
+\r
+                 if (c2 == '/')\r
+                   {\r
+                     goto outofcomment;\r
+                   }\r
+               }\r
+             else \r
+               {\r
+                 llfatalerror (cstring_makeLiteral ("Macro: bad comment!"));\r
+               }\r
+           }\r
+       outofcomment:\r
+         return macro_nextChar ();\r
+       }\r
+      else\r
+       {\r
+          /*** putchar does not work!  why?  puts to stdio...??! ***/\r
+          lmsavechar (c2);\r
+       }\r
+    }\r
+  return c;\r
+}\r
+\r
+/*\r
+** keeps semantic comments\r
+*/\r
+\r
+static char macro_nextCharC ()\r
+{\r
+  static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE;\r
+  char c;\r
+\r
+  c = char_fromInt (lminput ());\r
+\r
+  if (!in_quote && !in_char && c == '\\')\r
+    {\r
+      while ((c = char_fromInt (lminput ())) != '\0' && c != '\n')\r
+       {\r
+         ; /* skip to newline */\r
+       }\r
+      \r
+      context_incLineno ();\r
+      \r
+      if (c != '\0')\r
+       {\r
+         return macro_nextCharC ();\r
+       }\r
+      else\r
+       {\r
+         return c;\r
+       }\r
+    }\r
+  else if (!in_escape && c == '\"')\r
+    {\r
+      in_quote = !in_quote;\r
+    }\r
+  else if (!in_escape && c == '\'')\r
+    {\r
+      in_char = !in_char;\r
+    }\r
+  else if ((in_quote || in_char) && c == '\\')\r
+    {\r
+      in_escape = !in_escape;\r
+    }\r
+  else if ((in_quote || in_char) && in_escape)\r
+    {\r
+      in_escape = FALSE;\r
+    }\r
+  else if (!in_quote && c == '/')\r
+    {\r
+      char c2;\r
+      \r
+      if ((c2 = char_fromInt (lminput ())) == '*')\r
+       {\r
+         while (c2 != '\0')\r
+           {\r
+             while ((c2 = char_fromInt (lminput ())) != '\0' \r
+                    && c2 != '\n' && c2 != '*')\r
+               {\r
+                 ;\r
+               }\r
+             \r
+             if (c2 == '*')\r
+               {\r
+                 while ((c2 = char_fromInt (lminput ())) != '\0'\r
+                        && c2 == '*')\r
+                   {\r
+                     ;\r
+                   }\r
+\r
+                 if (c2 == '/') \r
+                   {\r
+                     goto outofcomment;\r
+                   }\r
+               }\r
+             else \r
+               {\r
+                 llfatalerror (cstring_makeLiteral ("Macro: bad comment!"));\r
+               }\r
+           }\r
+       outofcomment:\r
+         return macro_nextCharC ();\r
+       }\r
+      else\r
+       {\r
+         lmsavechar (c2);\r
+       }\r
+    }\r
+  return c;\r
+}\r
+\r
+/*\r
+** skips whitespace (handles line continuations)\r
+** returns first non-whitespace character\r
+*/\r
+\r
+static char skip_whitespace ()\r
+{\r
+  char c;\r
+\r
+  while ((c = macro_nextChar ()) == ' ' || c == '\t')\r
+    {\r
+      ;\r
+    }\r
+\r
+  return c;\r
+}\r
+\r
+static void handleMacro ()\r
+{\r
+  cstring mac = cstring_undefined;\r
+  int macrocode;\r
+  char c;\r
+\r
+  while (currentColumn () > 2)\r
+    {\r
+      mac = cstring_appendChar (mac, ' ');\r
+      setTokLength (-1);\r
+    }\r
+\r
+  c = macro_nextCharC ();\r
+\r
+  if (c >= '0' && c <= '9')\r
+    {\r
+      int i;\r
+\r
+      for (i = 0; i < ((c - '0') + 1); i++)\r
+       {\r
+         mac = cstring_appendChar (mac, ' ');\r
+       }\r
+    }\r
+  else\r
+    {\r
+      BADBRANCH;\r
+    }\r
+\r
+  while (((c = macro_nextCharC ()) != '\0') && (c != '\n'))\r
+    {\r
+      mac = cstring_appendChar (mac, c);\r
+    }\r
+\r
+  \r
+  macrocode = tokenMacroCode (mac);\r
+\r
+  if (macrocode == BADTOK && !isArtificial (mac))\r
+    {\r
+      context_addMacroCache (mac);\r
+    }\r
+  else\r
+    {\r
+      cstring_free (mac);\r
+    }\r
+\r
+  if (c == '\n')\r
+    {\r
+      context_incLineno ();\r
+    }\r
+}\r
+\r
+static bool processMacro (void)\r
+{\r
+  uentry e2;\r
+  ctype ct;\r
+  int noparams = 0;\r
+  cstring fname = cstring_undefined;\r
+  bool res = TRUE;\r
+  bool isspecfcn = FALSE;\r
+  bool isiter = FALSE;\r
+  bool skipparam = FALSE;\r
+  bool isenditer = FALSE;\r
+  bool unknownm = FALSE;\r
+  bool hasParams = FALSE;\r
+  bool emptyMacro = FALSE;\r
+  char c = skip_whitespace ();\r
+  fileloc loc = fileloc_noColumn (g_currentloc);\r
+\r
+  /* are both of these necessary?  what do they mean? */\r
+  uentryList specparams = uentryList_undefined;\r
+  uentryList pn = uentryList_undefined;\r
+\r
+  context_resetMacroMissingParams ();\r
+\r
+  if (c == '\0' || c == '\n')\r
+    {\r
+      llcontbug (cstring_makeLiteral ("Bad macro"));\r
+      fileloc_free (loc);\r
+      return FALSE;\r
+    }\r
+  \r
+  fname = cstring_appendChar (fname, c);  \r
+\r
+  while ((c = macro_nextChar ()) != '(' && c != '\0'\r
+        && c != ' ' && c != '\t' && c != '\n')\r
+    {\r
+      fname = cstring_appendChar (fname, c);\r
+    }\r
+\r
+  if (c == ' ' || c == '\t' || c == '\n')\r
+    {\r
+      char oldc = c;\r
+\r
+      if (c != '\n')\r
+       {\r
+         while (c == ' ' || c == '\t')\r
+           {\r
+             c = macro_nextChar ();\r
+           }\r
+         unput (c);\r
+       }\r
+\r
+      if (c == '\n')\r
+       {\r
+         emptyMacro = TRUE;\r
+         unput (c);\r
+       }\r
+\r
+      c = oldc;\r
+    }\r
+\r
+  hasParams = (c == '(');\r
+  \r
+  if (usymtab_exists (fname))\r
+    {\r
+      e2 = usymtab_lookupExpose (fname);\r
+      ct = uentry_getType (e2);\r
+\r
+      if (uentry_isCodeDefined (e2) \r
+         && fileloc_isUser (uentry_whereDefined (e2)))\r
+       {\r
+         if (optgenerror \r
+             (FLG_MACROREDEF,\r
+              message ("Macro %s already defined", fname),\r
+              loc))\r
+           {\r
+             uentry_showWhereDefined (e2);\r
+             uentry_clearDefined (e2);\r
+           }\r
+\r
+         if (uentry_isFunction (e2))\r
+           {\r
+             uentry_setType (e2, ctype_unknown);\r
+             ct = ctype_unknown;\r
+             unknownm = TRUE;\r
+             context_enterUnknownMacro (e2); \r
+           }\r
+         else\r
+           {\r
+             context_enterConstantMacro (e2);\r
+           }\r
+       }\r
+      else\r
+       {\r
+         if (uentry_isForward (e2) && uentry_isFunction (e2))\r
+           {\r
+             unknownm = TRUE;\r
+\r
+             voptgenerror \r
+               (FLG_MACROFCNDECL,\r
+                message\r
+                ("Parameterized macro has no prototype or specification: %s ", \r
+                 fname),\r
+                loc);\r
+             \r
+             ct = ctype_unknown;\r
+             uentry_setType (e2, ctype_unknown);\r
+             uentry_setFunctionDefined (e2, loc); \r
+             uentry_setUsed (e2, fileloc_undefined);\r
+             context_enterUnknownMacro (e2); \r
+           }\r
+         else\r
+           {\r
+             if (uentry_isIter (e2))\r
+               {\r
+                 isiter = TRUE;\r
+                 specparams = uentry_getParams (e2);\r
+                 noparams = uentryList_size (specparams);\r
+                 uentry_setDefined (e2, loc);\r
+                 context_enterIterDef (e2); \r
+               }\r
+             else if (uentry_isEndIter (e2))\r
+               {\r
+                 isenditer = TRUE;\r
+                 uentry_setDefined (e2, loc);\r
+                 context_enterIterEnd (e2); /* don't care about it now */\r
+                 /* but should parse like an iter! */\r
+               }\r
+             else if (uentry_isConstant (e2))\r
+               {\r
+                 if (hasParams)\r
+                   {\r
+                     voptgenerror \r
+                       (FLG_INCONDEFS, \r
+                        message ("Constant %s implemented as parameterized macro",\r
+                                 fname),\r
+                        g_currentloc);\r
+                     \r
+                     uentry_showWhereSpecified (e2);\r
+                     uentry_setType (e2, ctype_unknown);\r
+                     uentry_makeConstantFunction (e2);\r
+                     uentry_setDefined (e2, g_currentloc);\r
+                     uentry_setFunctionDefined (e2, g_currentloc);\r
+                     context_enterUnknownMacro (e2); \r
+                   }\r
+                 else\r
+                   {\r
+                     if (!uentry_isSpecified (e2))\r
+                       {\r
+                         fileloc oloc = uentry_whereDeclared (e2);\r
+\r
+                         if (fileloc_isLib (oloc))\r
+                           {\r
+                             ;\r
+                           }\r
+                         else if (fileloc_isUndefined (oloc)\r
+                                  || fileloc_isPreproc (oloc))\r
+                           {\r
+                             if (!emptyMacro)\r
+                               {\r
+                                 voptgenerror\r
+                                   (FLG_MACROCONSTDECL,\r
+                                    message \r
+                                    ("Macro constant %q not declared",\r
+                                     uentry_getName (e2)),\r
+                                    loc);                       \r
+                               }\r
+                           }\r
+                         else if (!fileloc_withinLines (oloc, loc, 2))\r
+                           { /* bogus!  will give errors if there is too much whitespace */\r
+                             voptgenerror\r
+                               (FLG_SYNTAX,\r
+                                message \r
+                                ("Macro constant name %s does not match name in "\r
+                                 "previous constant declaration.  This constant "\r
+                                 "is declared at %q", fname, \r
+                                 fileloc_unparse (oloc)),\r
+                                loc);\r
+                           }\r
+                       }\r
+\r
+                     context_enterConstantMacro (e2);        \r
+                     cstring_free (fname);\r
+                     fileloc_free (loc);\r
+                     return res;\r
+                   }\r
+\r
+               }\r
+             else if (ctype_isFunction (ct))\r
+               {\r
+                 isspecfcn = TRUE;\r
+                 specparams = ctype_argsFunction (ct);\r
+                 noparams = uentryList_size (specparams);\r
+                 \r
+                 uentry_setFunctionDefined (e2, loc); \r
+                 context_enterMacro (e2);\r
+               }\r
+             else if (uentry_isVar (e2))\r
+               {\r
+                 if (hasParams)\r
+                   {\r
+                     voptgenerror\r
+                       (FLG_INCONDEFS,\r
+                        message ("Variable %s implemented as parameterized macro", \r
+                                 fname),\r
+                        loc);\r
+\r
+                     uentry_showWhereSpecified (e2);\r
+                     uentry_setType (e2, ctype_unknown);\r
+                     uentry_makeVarFunction (e2);\r
+                     uentry_setDefined (e2, g_currentloc);\r
+                     uentry_setFunctionDefined (e2, g_currentloc);\r
+                     context_enterUnknownMacro (e2); \r
+                   }\r
+                 else\r
+                   {\r
+                     uentry ucons = uentry_makeConstant (fname,\r
+                                                         ctype_unknown,\r
+                                                         loc);\r
+                     if (uentry_isExpandedMacro (e2))\r
+                       {\r
+                         ; /* okay */\r
+                       }\r
+                     else\r
+                       {\r
+                         if (optgenerror \r
+                             (FLG_INCONDEFS,\r
+                              message ("Variable %s implemented by a macro",\r
+                                       fname),\r
+                              loc))\r
+                           {\r
+                             uentry_showWhereSpecified (e2);\r
+                           }\r
+                       }\r
+\r
+                     uentry_setDefined (e2, loc);\r
+                     uentry_setUsed (ucons, loc);\r
+\r
+                     context_enterConstantMacro (ucons);\r
+                     uentry_markOwned (ucons);\r
+                     cstring_free (fname);\r
+                     return res;\r
+                   }\r
+               }\r
+             else\r
+               {\r
+                 if (uentry_isDatatype (e2))\r
+                   {\r
+                     vgenhinterror \r
+                       (FLG_SYNTAX,\r
+                        message ("Type implemented as macro: %x", \r
+                                 uentry_getName (e2)),\r
+                        message ("A type is implemented using a macro definition.  A "\r
+                                 "typedef should be used instead."),\r
+                        g_currentloc);\r
+\r
+                     swallowMacro ();\r
+                     /* Must exit scope (not sure why a new scope was entered?) */\r
+                     usymtab_quietExitScope (g_currentloc);\r
+                     uentry_setDefined (e2, g_currentloc);\r
+                     res = FALSE;\r
+                   }\r
+                 else\r
+                   {\r
+                     llcontbug \r
+                       (message ("Unexpanded macro not function or constant: %q", \r
+                                 uentry_unparse (e2)));\r
+                     uentry_setType (e2, ctype_unknown);\r
+                     \r
+                     if (hasParams)\r
+                       {\r
+                         uentry_makeVarFunction (e2);\r
+                         uentry_setDefined (e2, g_currentloc);\r
+                         uentry_setFunctionDefined (e2, g_currentloc);\r
+                         context_enterUnknownMacro (e2); \r
+                       }\r
+                   }\r
+               }\r
+           }\r
+       }\r
+    }\r
+  else\r
+    {\r
+      uentry ce;\r
+\r
+      /* evans 2001-09-09 - if it has params, assume a function */\r
+      if (hasParams)\r
+       {\r
+         voptgenerror \r
+           (FLG_MACROMATCHNAME,\r
+            message ("Unexpanded macro %s does not match name of a declared "\r
+                     "function. The name used in the control "\r
+                     "comment on the previous line should match.",\r
+                     fname),\r
+            loc);\r
+         \r
+         ce = uentry_makeFunction (fname, ctype_unknown, \r
+                                   typeId_invalid,\r
+                                   globSet_undefined,\r
+                                   sRefSet_undefined,\r
+                                   warnClause_undefined,\r
+                                   fileloc_undefined);      \r
+         uentry_setUsed (ce, loc); /* perhaps bogus? */\r
+         e2 = usymtab_supEntryReturn (ce);\r
+         context_enterUnknownMacro (e2);             \r
+       }\r
+      else\r
+       {\r
+         voptgenerror \r
+           (FLG_MACROMATCHNAME,\r
+            message ("Unexpanded macro %s does not match name of a constant "\r
+                     "or iter declaration.  The name used in the control "\r
+                     "comment on the previous line should match.  "\r
+                     "(Assuming macro defines a constant.)", \r
+                     fname),\r
+            loc);\r
+         \r
+         ce = uentry_makeConstant (fname, ctype_unknown, fileloc_undefined);      \r
+         uentry_setUsed (ce, loc); /* perhaps bogus? */\r
+         e2 = usymtab_supEntryReturn (ce);\r
+         \r
+         context_enterConstantMacro (e2);            \r
+         cstring_free (fname);\r
+         fileloc_free (loc);\r
+         return res;\r
+       }\r
+    }\r
+  \r
+  /* in macros, ( must follow immediatetly after name */\r
+  \r
+  if (hasParams)\r
+    {\r
+      int paramno = 0;\r
+      \r
+      c = skip_whitespace ();\r
+\r
+      while (c != ')' && c != '\0')\r
+       {\r
+         uentry  param;\r
+         bool    suppress = context_inSuppressRegion ();\r
+         cstring paramname = cstring_undefined;\r
+\r
+         /*\r
+         ** save the parameter location\r
+         */\r
+\r
+         decColumn ();\r
+         context_saveLocation ();\r
+         incColumn ();\r
+\r
+         while (c != ' ' && c != '\t' && c != ',' && c != '\0' && c != ')')\r
+           {\r
+             paramname = cstring_appendChar (paramname, c);\r
+             c = macro_nextChar ();\r
+           }\r
+         \r
+         if (c == ' ' || c == '\t') c = skip_whitespace ();\r
+\r
+         if (c == ',')\r
+           {\r
+             c = macro_nextChar ();\r
+             if (c == ' ' || c == '\t') c = skip_whitespace ();\r
+           }\r
+         \r
+         if (c == '\0')\r
+           {\r
+             llfatalerror (cstring_makeLiteral\r
+                           ("Bad macro syntax: uentryList"));\r
+           }\r
+         \r
+         if ((isspecfcn || isiter) && (paramno < noparams)\r
+             && !uentry_isElipsisMarker (uentryList_getN \r
+                                         (specparams, paramno)))\r
+           {\r
+             fileloc sloc = context_getSaveLocation ();\r
+             uentry decl = uentryList_getN (specparams, paramno);\r
+             sRef sr;\r
+             \r
+             param = uentry_nameCopy (paramname, decl);\r
+                             \r
+             uentry_setParam (param);\r
+             sr = sRef_makeParam (paramno, uentry_getType (param), stateInfo_makeLoc (sloc));\r
+\r
+             if (sRef_getNullState (sr) == NS_ABSNULL)\r
+               {\r
+                 ctype pt = ctype_realType (uentry_getType (param));\r
+\r
+                 if (ctype_isUser (pt))\r
+                   {\r
+                     uentry te = usymtab_getTypeEntrySafe (ctype_typeId (pt));\r
+                     \r
+                     if (uentry_isValid (te))\r
+                       {\r
+                         sRef_setStateFromUentry (sr, te);\r
+                       }\r
+                   }\r
+                 else\r
+                   {\r
+                     sRef_setNullState (sr, NS_UNKNOWN, sloc);\r
+                   }\r
+               }\r
+\r
+             uentry_setSref (param, sr);\r
+             uentry_setDeclaredForceOnly (param, sloc);\r
+\r
+             skipparam = isiter && uentry_isOut (uentryList_getN (specparams, paramno));\r
+           }\r
+         else\r
+           {\r
+             fileloc sloc = context_getSaveLocation ();\r
+\r
+             param = uentry_makeVariableSrefParam \r
+               (paramname, ctype_unknown, fileloc_copy (sloc), \r
+                sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (sloc)));\r
+             DPRINTF (("Unknown param: %s", uentry_unparseFull (param)));\r
+             cstring_free (paramname);\r
+\r
+             sRef_setPosNull  (uentry_getSref (param), sloc);\r
+             uentry_setDeclaredForce (param, sloc);\r
+\r
+             skipparam = FALSE;\r
+             fileloc_free (sloc);\r
+           }\r
+\r
+         if (!skipparam)\r
+           {\r
+             llassert (!uentry_isElipsisMarker (param));\r
+\r
+             if (!suppress)\r
+               {\r
+                 sRef_makeUnsafe (uentry_getSref (param));\r
+               }\r
+             \r
+             pn = uentryList_add (pn, uentry_copy (param));\r
+             usymtab_supEntry (param);\r
+           }\r
+         else\r
+           {\r
+             /* don't add param */\r
+             uentry_free (param);\r
+           }\r
+\r
+         if (c == ',') \r
+           {\r
+             (void) macro_nextChar ();\r
+             c = skip_whitespace ();\r
+           }\r
+\r
+         paramno++;\r
+       }\r
+      \r
+      if (c == ')')\r
+       {\r
+         if (isspecfcn || isiter)\r
+           {\r
+             if (paramno != noparams && noparams >= 0)\r
+               {\r
+                 advanceLine ();\r
+\r
+                 voptgenerror \r
+                   (FLG_INCONDEFS,\r
+                    message ("Macro %s specified with %d args, defined with %d", \r
+                             fname, noparams, paramno),\r
+                    g_currentloc);\r
+\r
+                 uentry_showWhereSpecified (e2);\r
+                 uentry_resetParams (e2, pn);\r
+               }\r
+           }\r
+         else\r
+           {\r
+             uentry_resetParams (e2, pn);\r
+           }\r
+       }\r
+    }\r
+  else\r
+    {\r
+      /*\r
+      ** the form should be:\r
+      **\r
+      ** # define newname oldname\r
+      ** where oldname refers to a function matching the specification\r
+      ** of newname.\r
+      */\r
+\r
+      if (unknownm)\r
+       {\r
+         sRef_setGlobalScope ();\r
+         usymtab_supGlobalEntry (uentry_makeVariableLoc (fname, ctype_unknown));\r
+         sRef_clearGlobalScope ();\r
+       }\r
+      else\r
+       {\r
+         context_setMacroMissingParams ();\r
+       }\r
+    }\r
+  \r
+  \r
+  /* context_setuentryList (pn); */\r
+  usymtab_enterScope ();\r
+\r
+  fileloc_free (loc);\r
+  cstring_free (fname);\r
+\r
+  return res;\r
+}\r
+\r
+static bool handleSpecial (char *yyt)\r
+{\r
+  char *l = mstring_create (MAX_NAME_LENGTH);\r
+  static bool reportcpp = FALSE;\r
+  int lineno = 0;\r
+  char c;\r
+  char *ol;\r
+  cstring olc;\r
+  \r
+  strcpy (l, yyt + 1);\r
+\r
+  /* Need to safe original l for deallocating. */\r
+  ol = l;\r
+\r
+  l += strlen (yyt) - 1;\r
+  \r
+  while ((c = char_fromInt (lminput ())) != '\n' && c != '\0')\r
+    {\r
+      *l++ = c;\r
+    }\r
+\r
+  *l = '\0';\r
+  olc = cstring_fromChars (ol);\r
+  \r
+  if (cstring_equalPrefixLit (olc, "pragma"))\r
+    {\r
+      char *pname = mstring_create (longUnsigned_fromInt (MAX_PRAGMA_LEN));\r
+      char *opname = pname;\r
+      char *ptr = ol + 6; /* pragma is six characters, plus space */\r
+      int len = 0;\r
+      \r
+      \r
+      /* skip whitespace */\r
+      while (((c = *ptr) != '\0') && isspace (c))\r
+       {\r
+         ptr++;\r
+       }\r
+\r
+      \r
+      while (((c = *ptr) != '\0') && !isspace (c))\r
+       {\r
+         len++;\r
+\r
+         if (len > MAX_PRAGMA_LEN)\r
+           {\r
+             break;\r
+           }\r
+\r
+         ptr++;\r
+         *pname++ = c;\r
+       }\r
+\r
+      *pname = '\0';\r
+      \r
+      if (len == PRAGMA_LEN_EXPAND \r
+         && mstring_equal (opname, PRAGMA_EXPAND))\r
+       {\r
+         cstring exname = cstring_undefined;\r
+         uentry ue;\r
+         \r
+         ptr++; \r
+         while (((c = *ptr) != '\0') && !isspace (c))\r
+           {\r
+             exname = cstring_appendChar (exname, c);\r
+             ptr++;\r
+           }\r
+            \r
+         \r
+         ue = usymtab_lookupExposeGlob (exname);\r
+         \r
+         if (uentry_isExpandedMacro (ue))\r
+           {\r
+             if (fileloc_isPreproc (uentry_whereDefined (ue)))\r
+               {\r
+                 fileloc_setColumn (g_currentloc, 1);\r
+                 uentry_setDefined (ue, g_currentloc);\r
+               }\r
+           }\r
+\r
+         cstring_free (exname);\r
+       }\r
+    }\r
+  else if (cstring_equalPrefixLit (olc, "ident"))\r
+    {\r
+      /* Some pre-processors will leave these in the code.  Ignore rest of line */\r
+    }\r
+  /*\r
+  ** Yuk...Win32 filenames can have spaces in them...we need to read\r
+  ** to the matching end quote.\r
+  */\r
+  else if ((sscanf (ol, "line %d \"", &lineno) == 1)\r
+          || (sscanf (ol, " %d \"", &lineno) == 1))\r
+    {\r
+      char *tmp = ol;\r
+      cstring fname;\r
+      fileId fid;\r
+\r
+      /*@access cstring@*/\r
+      while (*tmp != '\"' && *tmp != '\0')\r
+       {\r
+         tmp++;\r
+       }\r
+\r
+      llassert (*tmp == '\"');\r
+\r
+      tmp++;\r
+\r
+      fname = tmp;\r
+      \r
+      while (*tmp != '\"' && *tmp != '\0')\r
+       {\r
+         tmp++;\r
+       }\r
+\r
+      llassert (*tmp == '\"');\r
+\r
+      *tmp = '\0';\r
+\r
+# if defined(OS2) || defined(MSDOS) || defined(WIN32)\r
+\r
+      /*\r
+      ** DOS-like path delimiters get delivered in pairs, something like \r
+      ** \"..\\\\file.h\", so we have to make it normal again. We do NOT\r
+      ** remove the pre dirs yet as we usually specify tmp paths relative\r
+      ** to the current directory, so tmp files would not get found in\r
+      ** the hash table.  If this method fails we try it again later. \r
+      */\r
+\r
+      {\r
+       char *stmp = fname;\r
+       \r
+       /*\r
+       ** Skip past the drive marker.\r
+       */\r
+       \r
+       if (strchr (stmp, ':') != NULL)\r
+         {\r
+           stmp = strchr (stmp, ':') + 1;\r
+         }\r
+       \r
+       while ((stmp = strchr (stmp, CONNECTCHAR)) != NULL )\r
+         {\r
+           if (*(stmp+1) == CONNECTCHAR)\r
+             {\r
+               memmove (stmp, stmp+1, strlen (stmp));\r
+             }\r
+           \r
+           stmp++;\r
+         }\r
+       \r
+       fid = fileTable_lookupBase (context_fileTable (), fname);\r
+       if (!(fileId_isValid (fid)))\r
+         {\r
+           fname = removePreDirs (fname);\r
+           fid = fileTable_lookupBase (context_fileTable (), fname);\r
+         }\r
+      }\r
+# else  /* !defined(OS2) && !defined(MSDOS) */\r
+      fname = removePreDirs (fname);\r
+      fid = fileTable_lookupBase (context_fileTable (), fname);      \r
+# endif /* !defined(OS2) && !defined(MSDOS) */\r
+      \r
+      if (!(fileId_isValid (fid)))\r
+       {\r
+         if (context_inXHFile ())\r
+           {\r
+             fid = fileTable_addXHFile (context_fileTable (), fname);\r
+           }\r
+         else if (isHeaderFile (fname))\r
+           {\r
+             fid = fileTable_addHeaderFile (context_fileTable (), fname);\r
+           }\r
+         else\r
+           {\r
+             fid = fileTable_addFile (context_fileTable (), fname);\r
+           }\r
+       }\r
+      \r
+      setFileLine (fid, lineno);\r
+      /*@noaccess cstring@*/\r
+    }\r
+  else if ((sscanf (ol, "line %d", &lineno) == 1) \r
+          || (sscanf (ol, " %d", &lineno) == 1))\r
+    {\r
+      setLine (lineno); /* next line is <cr> */\r
+    }\r
+  else\r
+    {\r
+      if (mstring_equal (ol, "")) {\r
+       DPRINTF (("Empty pp command!"));\r
+       /*\r
+       ** evs 2000-05-16: This is a horrible kludge, to get around a bug (well, difficulty) in the pre-processor.\r
+       ** We handle a plain # in the input file, by echoing it, and ignoring it in the post-pp-file.\r
+       */\r
+       mstring_free (ol);\r
+       return FALSE;\r
+      } else {\r
+       if (!reportcpp)\r
+         {\r
+           \r
+         } else {\r
+           llbug (message ("File contains preprocessor command: #%s", \r
+                           cstring_fromChars (ol)));\r
+           reportcpp = TRUE;\r
+         }\r
+      }\r
+      \r
+      sfree (ol);\r
+      return TRUE;\r
+    }\r
+\r
+  sfree (ol);\r
+  return FALSE;\r
+}\r
+  \r
+static int handleLlSpecial ()\r
+{ \r
+  bool hasnl = FALSE;\r
+  int ic; \r
+  char c;\r
+  char *s = mstring_createEmpty ();\r
+  char *os; \r
+  int tok;\r
+  int charsread = 0;\r
+  fileloc loc;\r
+\r
+  loc = fileloc_copy (g_currentloc);\r
+  DPRINTF (("Handle special: %s", fileloc_unparse (loc)));\r
+\r
+  while (((ic = ninput ()) != 0) && isalpha (ic))\r
+    {\r
+      c = (char) ic;\r
+      s = mstring_append (s, c);\r
+      charsread++;\r
+    }\r
+\r
+  DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));\r
+  os = s;\r
+\r
+  if (charsread == 0 && ic == (int) AFTER_COMMENT_MARKER[0])\r
+    {\r
+      ic = ninput ();\r
+\r
+      llassert (ic == AFTER_COMMENT_MARKER[1]);\r
+            \r
+      if (*s == '\0')\r
+       {\r
+         sfree (os);\r
+         fileloc_free (loc);\r
+         return QNOMODS; /* special token no modifications token */\r
+       }\r
+    }\r
+  \r
+  DPRINTF (("Coment marker: %s", os));\r
+  tok = commentMarkerToken (cstring_fromChars (os));\r
+\r
+  if (tok != BADTOK)\r
+    {\r
+      tokLength = charsread;\r
+      sfree (os);\r
+      inSpecPart = TRUE;\r
+      fileloc_free (loc);\r
+      return tok;\r
+    }\r
+\r
+  DPRINTF (("Not a comment marker..."));\r
+  /* Add rest of the comment */\r
+  \r
+  if (ic != 0 && ic != EOF)\r
+    {\r
+      c = (char) ic;\r
+      \r
+      s = mstring_append (s, c);\r
+      charsread++;\r
+\r
+      while (((ic = ninput ()) != 0) && (ic != EOF)\r
+            && (ic != AFTER_COMMENT_MARKER[0]))\r
+       {\r
+         c = (char) ic;\r
+\r
+         /* evans 2001-09-01 added to prevent assertion failures for uncloses syntactic comments */\r
+\r
+         if (c == '\n') {\r
+           hasnl = TRUE; /* This prevents tokLength from being set later. */\r
+           tokLength = 0; \r
+\r
+           voptgenerror\r
+             (FLG_SYNTAX, \r
+              message ("Likely parse error: syntactic comment token spans multiple lines: %s",\r
+                       cstring_fromChars (s)),\r
+              g_currentloc);\r
+         }\r
+\r
+         s = mstring_append (s, c);\r
+         charsread++;\r
+       }\r
+    }\r
+\r
+  DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));\r
+\r
+  if (ic == AFTER_COMMENT_MARKER[0]) \r
+    {\r
+      int nc = ninput ();\r
+      llassert ((char) nc ==  AFTER_COMMENT_MARKER[1]);\r
+      charsread++;\r
+    }\r
+\r
+  os = s;\r
+\r
+  while (*s == ' ' || *s == '\t' || *s == '\n') \r
+    {\r
+      s++;\r
+    }\r
+\r
+  if (*s == '-' || *s == '+' || *s == '=') /* setting flags */\r
+    {\r
+      c = *s;\r
+\r
+      while (c == '-' || c == '+' || c == '=')\r
+       {\r
+         ynm set = ynm_fromCodeChar (c);\r
+         cstring thisflag;\r
+\r
+         s++;\r
+         \r
+         thisflag = cstring_fromChars (s);\r
+         \r
+         while ((c = *s) != '\0' && (c != '-') && (c != '=')\r
+                && (c != '+') && (c != ' ') && (c != '\t') && (c != '\n'))\r
+           {\r
+             s++;\r
+           }\r
+\r
+         *s = '\0';\r
+\r
+         if (!context_getFlag (FLG_NOCOMMENTS))\r
+           {\r
+             cstring flagname = thisflag;\r
+             flagcode fflag = identifyFlag (flagname);\r
+               \r
+             if (flagcode_isSkip (fflag))\r
+               {\r
+                 ;\r
+               }\r
+             else if (flagcode_isInvalid (fflag))\r
+               {\r
+                 if (isMode (flagname))\r
+                   {\r
+                     if (ynm_isMaybe (set))\r
+                       {\r
+                         llerror\r
+                           (FLG_BADFLAG, \r
+                            message \r
+                            ("Semantic comment attempts to restore flag %s.  "\r
+                             "A mode flag cannot be restored.",\r
+                             flagname));\r
+                       }\r
+                     else\r
+                       {\r
+                         context_setMode (flagname);\r
+                       }\r
+                   }\r
+                 else\r
+                   {\r
+                     voptgenerror\r
+                       (FLG_UNRECOGFLAGCOMMENTS,\r
+                        message ("Unrecognized option in semantic comment: %s", \r
+                                 flagname),\r
+                        g_currentloc);\r
+                   }\r
+               }\r
+             else if (flagcode_isGlobalFlag (fflag))\r
+               {\r
+                 voptgenerror\r
+                   (FLG_BADFLAG, \r
+                    message \r
+                    ("Semantic comment attempts to set global flag %s.  "\r
+                     "A global flag cannot be set locally.",\r
+                     flagname),\r
+                    g_currentloc);\r
+               }\r
+             else\r
+               {\r
+                 context_fileSetFlag (fflag, set);\r
+                 \r
+                 if (flagcode_hasArgument (fflag))\r
+                   {\r
+                     if (ynm_isMaybe (set))\r
+                       {\r
+                         voptgenerror\r
+                           (FLG_BADFLAG, \r
+                            message \r
+                            ("Semantic comment attempts to restore flag %s.  "\r
+                             "A flag for setting a value cannot be restored.",\r
+                             flagname),\r
+                            g_currentloc);\r
+                       }\r
+                     else\r
+                       { /* cut-and-pastied from llmain...blecch */\r
+                         cstring extra = cstring_undefined;\r
+                         char *rest;\r
+                         char *orest;\r
+                         char rchar;\r
+                         \r
+                         *s = c;\r
+                         rest = mstring_copy (s);\r
+                         orest = rest;\r
+                         *s = '\0';\r
+                         \r
+                         while ((rchar = *rest) != '\0'\r
+                                && (isspace (rchar)))\r
+                           {\r
+                             rest++;\r
+                             s++;\r
+                           }\r
+                         \r
+                         while ((rchar = *rest) != '\0'\r
+                                && !isspace (rchar))\r
+                           {\r
+                             extra = cstring_appendChar (extra, rchar);\r
+                             rest++; \r
+                             s++;\r
+                           }\r
+                         \r
+                         sfree (orest);\r
+                         \r
+                         if (cstring_isUndefined (extra))\r
+                           {\r
+                             llerror \r
+                               (FLG_BADFLAG,\r
+                                message\r
+                                ("Flag %s (in semantic comment) must be followed by an argument",\r
+                                 flagcode_unparse (fflag)));\r
+                           }\r
+                         else\r
+                           {\r
+                             s--;\r
+                             \r
+                             if (flagcode_hasValue (fflag))\r
+                               {\r
+                                 setValueFlag (fflag, extra);\r
+                               }\r
+                             else if (flagcode_hasString (fflag))\r
+                               {\r
+                                 setStringFlag (fflag, extra);\r
+                               }\r
+                             else\r
+                               {\r
+                                 BADEXIT;\r
+                               }\r
+                           }\r
+                       }\r
+                   }\r
+               }\r
+           }\r
+         else\r
+           {\r
+             ;\r
+           }\r
+\r
+         *s = c;\r
+         while ((c == ' ') || (c == '\t') || (c == '\n'))\r
+           {\r
+             c = *(++s);\r
+           }\r
+       } \r
+\r
+      if (context_inHeader () && !isArtificial (cstring_fromChars (os)))\r
+       {\r
+         DPRINTF (("Here adding comment: %s", os));\r
+         context_addComment (cstring_fromCharsNew (os));\r
+       }\r
+      else\r
+       {\r
+         ;\r
+       }\r
+    }\r
+  else\r
+    {\r
+      char *t = s;\r
+      int macrocode;\r
+      char tchar = '\0';\r
+      annotationInfo ainfo;\r
+\r
+      while (*s != '\0' && *s != ' ' && *s != '\t' && *s != '\n') \r
+       {\r
+         s++;\r
+       }\r
+\r
+      if (*s != '\0') \r
+       {\r
+         tchar = *s;\r
+         *s = '\0';\r
+         s++;\r
+       }\r
+      \r
+      t = cstring_toCharsSafe (cstring_downcase (cstring_fromChars (t)));\r
+      macrocode = tokenMacroCode (cstring_fromChars (t));\r
+\r
+      if (macrocode != BADTOK)\r
+       {\r
+         tokLength = hasnl ? 0 : mstring_length (t);\r
+         \r
+         sfree (t);\r
+         sfree (os);\r
+         fileloc_free (loc);\r
+\r
+         if (macrocode == SKIPTOK)\r
+           {\r
+             return BADTOK;\r
+           }\r
+\r
+         return macrocode;\r
+       }\r
+      \r
+      ainfo = context_lookupAnnotation (cstring_fromChars (os));\r
+      \r
+      if (annotationInfo_isDefined (ainfo)) {\r
+       DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));\r
+       /*@i324@*/ yylval.annotation = ainfo;\r
+       tokLength = 0;\r
+       sfree (os);\r
+       sfree (t);\r
+       fileloc_free (loc);\r
+       return CANNOTATION;\r
+      } \r
+\r
+      if (context_inHeader ())\r
+       {\r
+         if (tchar != '\0')\r
+           {\r
+             *(s-1) = tchar;\r
+           }\r
+         \r
+         if ((context_inMacro () || context_inGlobalContext ())\r
+             && macrocode != SKIPTOK\r
+             && !isArtificial (cstring_fromChars (os))) \r
+           {\r
+             DPRINTF (("Add comment: %s", os));\r
+             context_addComment (cstring_fromCharsNew (os));\r
+           }\r
+         else\r
+           {\r
+             ; \r
+           }\r
+         \r
+         if (tchar != '\0')\r
+           {\r
+             *(s-1) = '\0';\r
+           }\r
+       }\r
+\r
+      if (mstring_equal (t, "ignore"))\r
+       {\r
+         if (!context_getFlag (FLG_NOCOMMENTS))\r
+           {\r
+             context_enterSuppressRegion ();\r
+           }\r
+       }\r
+      else if ((*t == 'i' || *t == 't')\r
+              && (*(t + 1) == '\0'))\r
+       {\r
+         if (!context_getFlag (FLG_NOCOMMENTS)\r
+             && (*t == 'i' || context_getFlag (FLG_TMPCOMMENTS)))\r
+           {\r
+             context_enterSuppressLine (-1); /* infinite suppression */\r
+           }\r
+       }\r
+      else if (((*t == 'i') || (*t == 't'))\r
+              && ((*(t + 1) >= '0' && *(t + 1) <= '9')))\r
+       {\r
+         bool tmpcomment = (*t == 't');\r
+         int val = -1; \r
+         char *tt = t; /* don't mangle t, since it is free'd */\r
+         char lc = *(++tt);\r
+\r
+         if (lc >= '0' && lc <= '9')\r
+           {\r
+             val = (int)(lc - '0');\r
+             \r
+             lc = *(++tt);       \r
+             while (lc >= '0' && lc <= '9')\r
+               {\r
+                 val *= 10;\r
+                 val += lc - '0';\r
+                 lc = *(++tt);\r
+               }\r
+           }\r
+\r
+         \r
+         if (!context_getFlag (FLG_NOCOMMENTS)\r
+             && (!tmpcomment || context_getFlag (FLG_TMPCOMMENTS)))\r
+           {\r
+             context_enterSuppressLine (val);\r
+           }\r
+       }\r
+      else if (mstring_equal (t, "end"))\r
+       {\r
+         if (!context_getFlag (FLG_NOCOMMENTS))\r
+           {\r
+             context_exitSuppressRegion ();\r
+           }\r
+       }\r
+      else if (mstring_equal (t, "notfunction"))\r
+       {\r
+        ; /* handled by pcpp */\r
+       }\r
+      else if (mstring_equal (t, "access"))\r
+       {\r
+         cstring tname;\r
+         \r
+         while (TRUE)\r
+           {\r
+             while ((c = *s) && (c == ' ' || c == '\t' || c == '\n'))\r
+               {\r
+                 s++;\r
+               }\r
+             \r
+             if (c == '\0')\r
+               {\r
+                   break;\r
+               }\r
+\r
+             tname = cstring_fromChars (s);\r
+             \r
+             while ((c = *s) != '\0' && c != ' ' \r
+                    && c != '\t' && c != '\n' && c != ',') \r
+               {\r
+                 s++;\r
+               }\r
+\r
+             *s = '\0';\r
+\r
+             DPRINTF (("Access %s", tname));\r
+\r
+             if (!context_getFlag (FLG_NOCOMMENTS) \r
+                 && !context_getFlag (FLG_NOACCESS))\r
+               {\r
+                 if (usymtab_existsType (tname))\r
+                   {\r
+                     typeId uid = usymtab_getTypeId (tname);\r
+                     uentry ue = usymtab_getTypeEntry (uid);\r
+\r
+                     if (uentry_isAbstractDatatype (ue))\r
+                       {\r
+                         context_addFileAccessType (uid);\r
+                         DPRINTF (("Adding access to: %s / %d", tname, uid));\r
+                       }\r
+                     else\r
+                       {\r
+                         voptgenerror\r
+                           (FLG_COMMENTERROR,\r
+                            message\r
+                            ("Non-abstract type %s used in access comment",\r
+                             tname),\r
+                            g_currentloc);\r
+                       }\r
+                   }\r
+                 else\r
+                   {\r
+                     if (!(context_inSuppressRegion ()\r
+                           || context_inSuppressZone (g_currentloc)))\r
+                       {\r
+                         voptgenerror\r
+                           (FLG_COMMENTERROR,\r
+                            message\r
+                            ("Unrecognized type %s used in access comment",\r
+                             tname),\r
+                            g_currentloc);\r
+                       }\r
+                   }\r
+               }\r
+             \r
+             if (c != '\0') \r
+               {\r
+                 s++;\r
+               }\r
+             \r
+             if (c != ',' && c != ' ')\r
+               {\r
+                 break;\r
+               }\r
+           }\r
+       }\r
+      else if (mstring_equal (t, "noaccess"))\r
+       {\r
+         cstring tname;\r
+         char lc;\r
+         \r
+         while (TRUE)\r
+           {\r
+             while ((lc = *s) && (lc == ' ' || lc == '\t' || lc == '\n')) \r
+               {\r
+                 s++;\r
+               }\r
+             \r
+             if (lc == '\0')\r
+               {\r
+                break;\r
+               }\r
+\r
+             tname = cstring_fromChars (s);\r
+             \r
+             while ((lc = *s) != '\0' && lc != ' ' && lc != '\t' \r
+                    && lc != '\n' && lc != ',') \r
+               {\r
+                 s++;\r
+               }\r
+\r
+             *s = '\0';\r
+\r
+             if (!context_getFlag (FLG_NOCOMMENTS) \r
+                 && !context_getFlag (FLG_NOACCESS))\r
+               {\r
+                 if (usymtab_existsType (tname))\r
+                   {\r
+                     typeId tuid = usymtab_getTypeId (tname);\r
+                     \r
+                     if (context_couldHaveAccess (tuid))\r
+                       {\r
+                         DPRINTF (("Removing access: %s", tname));\r
+                         context_removeFileAccessType (tuid);\r
+                       }\r
+                     else\r
+                       {\r
+                         if (!(context_inSuppressRegion () \r
+                               || context_inSuppressZone (g_currentloc)))\r
+                           {\r
+                             uentry ue = usymtab_getTypeEntry (tuid);\r
+                             \r
+                             if (uentry_isAbstractDatatype (ue))\r
+                               {\r
+                                 voptgenerror\r
+                                   (FLG_COMMENTERROR,\r
+                                    message\r
+                                    ("Non-accessible abstract type %s used in noaccess comment",\r
+                                     tname),\r
+                                    g_currentloc);\r
+                               }\r
+                             else\r
+                               {\r
+                                 voptgenerror\r
+                                   (FLG_COMMENTERROR,\r
+                                    message\r
+                                    ("Non-abstract type %s used in noaccess comment",\r
+                                     tname),\r
+                                    g_currentloc);\r
+                               }\r
+                           }\r
+                       }\r
+                   }\r
+                 else\r
+                   {\r
+                     if (!(context_inSuppressRegion () \r
+                           || context_inSuppressZone (g_currentloc)))\r
+                       {\r
+                         voptgenerror\r
+                           (FLG_COMMENTERROR,\r
+                            message\r
+                            ("Unrecognized type %s used in noaccess comment",\r
+                             tname),\r
+                            g_currentloc);\r
+                       }\r
+                   }\r
+               }\r
+             \r
+             if (lc != '\0') \r
+               {\r
+                 s++;\r
+               }\r
+             \r
+             if (lc != ',' && lc != ' ')\r
+               {\r
+                 break;\r
+               }\r
+           }\r
+       }\r
+      else\r
+       {\r
+         voptgenerror (FLG_UNRECOGCOMMENTS, \r
+                       message ("Semantic comment unrecognized: %s", \r
+                                cstring_fromChars (os)), loc);\r
+       }\r
+\r
+      sfree (t);\r
+    }\r
+  \r
+  sfree (os);\r
+  fileloc_free (loc);\r
+  return BADTOK;\r
+}\r
+\r
+static /*@only@*/ cstring makeIdentifier (char *s)\r
+{\r
+  char *c = mstring_create (size_toInt (strlen (s)) + 1);\r
+  cstring id = cstring_fromChars (c);\r
+\r
+  while (isalnum (*s) || (*s == '_') || (*s == '$')) \r
+    {\r
+      *c++ = *s++;\r
+    }\r
+\r
+  *c = '\0';\r
+  return (id);\r
+}\r
+\r
+/*@observer@*/ /*@dependent@*/ uentry coerceId (cstring cn)\r
+{\r
+  if (!(usymtab_exists (cn)))\r
+    {\r
+      fileloc loc = fileloc_createExternal ();\r
+      \r
+      /*\r
+      ** We need to put this in a global scope, otherwise the sRef will be deallocated.\r
+      */\r
+      \r
+      uentry ce = uentry_makeUnrecognized (cn, loc);\r
+      \r
+      if (!context_inIterEnd ())\r
+       {\r
+         voptgenerror \r
+           (FLG_SYSTEMUNRECOG, \r
+            message ("Unrecognized (possibly system) identifier: %q", \r
+                     uentry_getName (ce)), \r
+            g_currentloc);\r
+       }\r
+      \r
+      return ce;\r
+    }\r
+  \r
+  return (usymtab_lookup (cn));\r
+}\r
+\r
+/*\r
+** like, coerceId, but doesn't supercede for iters\r
+*/\r
+\r
+/*@observer@*/ uentry coerceIterId (cstring cn)\r
+{\r
+  if (!(usymtab_exists (cn)))\r
+    {\r
+      return uentry_undefined;\r
+    }\r
+  \r
+  return (usymtab_lookup (cn));\r
+}\r
+\r
+/*@observer@*/ cstring LastIdentifier ()\r
+{\r
+  return (lastidprocessed);\r
+}\r
+\r
+static int processIdentifier (cstring id)\r
+{\r
+  uentry le;\r
+\r
+  if (context_getFlag (FLG_GRAMMAR))\r
+    {\r
+      lldiagmsg (message ("Process identifier: %s", id));\r
+    }\r
+\r
+  context_clearJustPopped ();\r
+  lastidprocessed = id; \r
+\r
+  if (context_inFunctionHeader ())\r
+    {\r
+      int tok = commentMarkerToken (id);\r
+      DPRINTF (("in function decl..."));\r
+\r
+      if (tok != BADTOK)\r
+       {\r
+         return tok;\r
+       }\r
+      else \r
+       {\r
+         tok = tokenMacroCode (id);\r
+\r
+         if (tok != BADTOK)\r
+           {\r
+             return tok;\r
+           }\r
+         else \r
+           {\r
+             annotationInfo ainfo;\r
+\r
+             if (expectingMetaStateName) \r
+               {\r
+                 metaStateInfo msinfo = context_lookupMetaStateInfo (id);\r
+\r
+                 if (metaStateInfo_isDefined (msinfo))\r
+                   {\r
+                     yylval.msinfo = msinfo;\r
+                     return METASTATE_NAME;\r
+                   }\r
+                 else\r
+                   {\r
+                     DPRINTF (("Not meta state name: %s", cstring_toCharsSafe (id)));\r
+                   }\r
+               }\r
+             \r
+             ainfo = context_lookupAnnotation (id);\r
+             \r
+             if (annotationInfo_isDefined (ainfo)) \r
+               {\r
+                 DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));\r
+                 /*@i324@*/ yylval.annotation = ainfo;\r
+                 return CANNOTATION;\r
+               }\r
+             else\r
+               {\r
+                 DPRINTF (("Not annotation: %s", id));\r
+               }\r
+           }\r
+       }\r
+    }\r
+\r
+  /* Consider handling: Defined by C99 as static const char __func__[] */\r
+\r
+  if (context_getFlag (FLG_GNUEXTENSIONS))\r
+    {\r
+      int tok = BADTOK;\r
+      \r
+      if (cstring_equalLit (id, "__stdcall")\r
+         || cstring_equalLit (id, "__cdecl")\r
+         || cstring_equalLit (id, "__extension__"))\r
+       {\r
+         return BADTOK;\r
+       }\r
+      else if (cstring_equalLit (id, "__volatile__"))\r
+       {\r
+         tok = QVOLATILE;\r
+       }\r
+      else if (cstring_equalLit (id, "__signed"))\r
+       {\r
+         tok = QSIGNED;\r
+       }\r
+      else if (cstring_equalLit (id, "__unsigned"))\r
+       {\r
+         tok = QUNSIGNED;\r
+       }\r
+      else if (cstring_equalLit (id, "__const__"))\r
+       {\r
+         tok = QCONST;\r
+       }\r
+      else if (cstring_equalLit (id, "__alignof__")) \r
+       {\r
+         tok = CALIGNOF; /* alignof is parsed like sizeof */\r
+       }\r
+      else if (cstring_equalLit (id, "__FUNCTION__")\r
+              || cstring_equalLit (id, "__PRETTY_FUNCTION__")) \r
+       {\r
+         /* These tokens hold the name of the current function as strings */\r
+         yylval.expr = exprNode_stringLiteral (id, fileloc_copy (g_currentloc));\r
+         tokLength = 0;\r
+         lastWasString = TRUE;\r
+         tok = CCONSTANT;\r
+         return tok;\r
+       }\r
+      else if (cstring_equalLit (id, "__attribute__")\r
+              || cstring_equalLit (id, "__asm__")\r
+              || cstring_equalLit (id, "_asm")\r
+              || cstring_equalLit (id, "__asm")\r
+              || cstring_equalLit (id, "__declspec"))\r
+       {\r
+         int depth = 0;\r
+         bool useparens = FALSE;\r
+         bool usebraces = FALSE;\r
+         bool inquote = FALSE;\r
+         bool inescape = FALSE;\r
+         int ic;\r
+\r
+         while ((ic = input ()) != EOF)\r
+           {\r
+                             \r
+             if (inescape)\r
+               {\r
+                 inescape = FALSE;\r
+               }\r
+             else if (ic == '\\')\r
+               {\r
+                 inescape = TRUE;\r
+               }\r
+             else if (ic == '\"')\r
+               {\r
+                 inquote = !inquote;\r
+               }\r
+             else if (!inquote)\r
+               {\r
+                 if (ic == '(')\r
+                   {\r
+                     if (!useparens)\r
+                       {\r
+                         if (!usebraces)\r
+                           {\r
+                             useparens = TRUE;\r
+                           }\r
+                       }\r
+\r
+                     if (useparens)\r
+                       {\r
+                         depth++;\r
+                       }\r
+                   }\r
+                 else if (ic == '{')\r
+                   {\r
+                     if (!usebraces)\r
+                       {\r
+                         if (!useparens)\r
+                           {\r
+                             usebraces = TRUE;\r
+                           }\r
+                       }\r
+\r
+                     if (usebraces)\r
+                       {\r
+                         depth++;\r
+                       }\r
+                   }\r
+                 else if (ic == ')' && useparens)\r
+                   {\r
+                     depth--;\r
+                     if (depth == 0) break;\r
+                   }\r
+                 else if (ic == '}' && usebraces)\r
+                   {\r
+                     depth--;\r
+                     if (depth == 0) break;\r
+                   }\r
+                 else if (ic == '}' \r
+                          && !usebraces && !useparens\r
+                          && cstring_equalLit (id, "__asm"))\r
+                   {\r
+                     /*\r
+                     ** We need this because some MS VC++ include files\r
+                     ** have __asm mov ... }\r
+                     ** Its a kludge, but otherwise would need to parse\r
+                     ** the asm code!\r
+                     */ \r
+                     return TRBRACE;\r
+                   }\r
+               }\r
+\r
+             if (ic == '\n')\r
+               {\r
+                 context_incLineno ();\r
+\r
+                 if (cstring_equalLit (id, "__asm")\r
+                     && !useparens && !usebraces)\r
+                   {\r
+                     break;\r
+                   }\r
+               }\r
+           }\r
+         \r
+         llassert ((useparens && ic == ')')\r
+                   || (usebraces && ic == '}')\r
+                   || (!useparens && !usebraces));\r
+\r
+         return BADTOK;\r
+       }\r
+      else if (cstring_equalLit (id, "inline")\r
+              || cstring_equalLit (id, "__inline")\r
+              || cstring_equalLit (id, "_inline")\r
+              || cstring_equalLit (id, "__inline__"))\r
+       {\r
+         tok = QINLINE;\r
+       }\r
+      \r
+      if (tok != BADTOK)\r
+       {\r
+         RETURN_TOK (tok);\r
+       }\r
+    }\r
+\r
+  le = usymtab_lookupSafe (id);\r
+\r
+  /*@-dependenttrans@*/\r
+  \r
+  if (uentry_isIter (le))\r
+    {\r
+      /*@i32@*/ yylval.entry = le;\r
+      return (ITER_NAME);\r
+    }\r
+  else if (uentry_isEndIter (le))\r
+    {\r
+      /*@i32@*/ yylval.entry = le;\r
+      return (ITER_ENDNAME);\r
+    }\r
+  else if (uentry_isUndefined (le))\r
+    {\r
+      yylval.cname = id;\r
+\r
+      /* avoid parse errors for certain system built ins */\r
+\r
+      if (g_expectingTypeName && (cstring_firstChar (id) == '_')\r
+         && (cstring_secondChar (id) == '_'))\r
+       {\r
+         return (TYPE_NAME_OR_ID);\r
+       }\r
+\r
+      return (NEW_IDENTIFIER);\r
+    }\r
+  else if (!uentry_isDeclared (le) && !uentry_isCodeDefined (le))\r
+    {\r
+      if (uentry_isDatatype (le))\r
+       {\r
+         yylval.cname = id;\r
+         return (NEW_IDENTIFIER);\r
+       }\r
+      else\r
+       {\r
+         /*@i32@*/ yylval.entry = le;            \r
+         return (IDENTIFIER); \r
+       }\r
+    }\r
+  else if (uentry_isDatatype (le))\r
+    {\r
+      if (!g_expectingTypeName)\r
+       {\r
+         yylval.cname = id;\r
+\r
+         return (NEW_IDENTIFIER);\r
+       }\r
+      else\r
+       {\r
+         yylval.ctyp = uentry_getAbstractType (le);\r
+         \r
+         uentry_setUsed (le, g_currentloc);\r
+         return (TYPE_NAME);\r
+       }\r
+    }\r
+  else\r
+    {\r
+      /*@i32@*/ yylval.entry = le;            \r
+      return (IDENTIFIER); \r
+    }\r
+\r
+  /*@=dependenttrans@*/\r
+}\r
+\r
+static bool processHashIdentifier (/*@only@*/ cstring id)\r
+{\r
+  if (context_inMacro () || context_inIterDef () ||\r
+      context_inIterEnd ())\r
+    {\r
+      uentry le;\r
+      \r
+      context_clearJustPopped ();\r
+\r
+      lastidprocessed = id; \r
+      le = usymtab_lookupSafe (id);\r
+\r
+      if (uentry_isParam (le) || uentry_isRefParam (le))\r
+       {\r
+         return TRUE;\r
+       }\r
+      else\r
+       {\r
+         return FALSE;\r
+       }\r
+    }\r
+  else\r
+    {\r
+      cstring_free (id);\r
+      return FALSE;\r
+    }\r
+}\r
+\r
+\r
+static /*@only@*/ exprNode processString ()\r
+{\r
+  exprNode res;\r
+  fileloc loc;\r
+  char *nl = strchr (yytext, '\n');\r
+  cstring ns = cstring_fromCharsNew (yytext);\r
+\r
+  if (nl == NULL)\r
+    {\r
+      loc = fileloc_copy (g_currentloc);\r
+      addColumn (cstring_length (ns));\r
+    }\r
+  else\r
+    {\r
+      char *lastnl = nl;\r
+\r
+      loc = fileloc_copy (g_currentloc);\r
+\r
+      context_incLineno ();\r
+      \r
+      while ((nl = strchr ((nl + 1), '\n')) != NULL)\r
+       {\r
+         context_incLineno ();\r
+         lastnl = nl;\r
+       }\r
+    }\r
+\r
+    \r
+  res = exprNode_stringLiteral (ns, loc);\r
+  return (res);\r
+}\r
+\r
+static \r
+char processChar ()\r
+{\r
+  char fchar;\r
+  char next;\r
+\r
+  llassert (*yytext != '\0');\r
+  fchar = *(yytext + 1);\r
+  if (fchar != '\\') return fchar;\r
+  \r
+  next = *(yytext + 2);\r
+  \r
+  switch (next)\r
+    {\r
+    case 'n': return '\n';\r
+    case 't': return '\t';\r
+    case '\"': return '\"';\r
+    case '\'': return '\'';\r
+    case '\\': return '\\';\r
+    default: return '\0';\r
+    }\r
+}\r
+\r
+static\r
+double processFloat ()\r
+{\r
+  double ret = atof (yytext);\r
+\r
+    return (ret);\r
+}\r
+\r
+static\r
+long processHex ()\r
+{\r
+  int index = 2;\r
+  long val = 0;\r
+\r
+  llassert (yytext[0] == '0'\r
+           && (yytext[1] == 'X' || yytext[1] == 'x'));\r
+\r
+  while (yytext[index] != '\0') {\r
+    int tval;\r
+    char c = yytext[index];\r
+\r
+    if (c >= '0' && c <= '9') {\r
+      tval = (int) c - (int) '0';\r
+    } else if (c >= 'A' && c <= 'F') {\r
+      tval = (int) c - (int) 'A' + 10;\r
+    } else if (c >= 'a' && c <= 'f') {\r
+      tval = (int) c - (int) 'a' + 10;\r
+    } else if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {\r
+      index++;\r
+      while (yytext[index] != '\0') {\r
+       if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {\r
+         ;\r
+       } else {\r
+         voptgenerror\r
+           (FLG_SYNTAX, \r
+            message ("Invalid character (%c) following specifier in hex constant: %s",\r
+                     c, cstring_fromChars (yytext)),\r
+            g_currentloc);\r
+       }\r
+       index++;\r
+      }\r
+\r
+      break;\r
+    } else {\r
+      voptgenerror\r
+       (FLG_SYNTAX, \r
+        message ("Invalid character (%c) in hex constant: %s",\r
+                 c, cstring_fromChars (yytext)),\r
+        g_currentloc);\r
+      break;\r
+    }\r
+\r
+    val = (val * 16) + tval;\r
+    index++;\r
+  }\r
+\r
+  DPRINTF (("Hex constant: %s = %ld", yytext, val));\r
+  return val;\r
+}\r
+\r
+static\r
+long processOctal ()\r
+{\r
+  int index = 1;\r
+  long val = 0;\r
+\r
+  llassert (yytext[0] == '0' && yytext[1] != 'X' && yytext[1] != 'x');\r
+    \r
+  while (yytext[index] != '\0') {\r
+    int tval;\r
+    char c = yytext[index];\r
+    \r
+    if (c >= '0' && c <= '7') {\r
+      tval = (int) c - (int) '0';\r
+    } else {\r
+      voptgenerror\r
+       (FLG_SYNTAX, \r
+        message ("Invalid character (%c) in octal constant: %s",\r
+                 c, cstring_fromChars (yytext)),\r
+        g_currentloc);\r
+      break;\r
+    }\r
+\r
+    val = (val * 8) + tval;\r
+    index++;\r
+  }\r
+\r
+  DPRINTF (("Octal constant: %s = %ld", yytext, val));\r
+  return val;\r
+}\r
+\r
+static\r
+long processDec ()\r
+{\r
+  return (atol (yytext));\r
+}\r
+\r
+static int\r
+processSpec (int tok)\r
+{\r
+  size_t length = strlen (yytext);\r
+  \r
+  if (inSpecPart)\r
+    {\r
+      setTokLengthT (length);\r
+      RETURN_TOK (tok);\r
+    }\r
+  else\r
+    {\r
+      \r
+      context_saveLocation ();\r
+      setTokLengthT (length);\r
+      return (processIdentifier (makeIdentifier (yytext)));\r
+    }\r
+}\r
+\r
+void cscanner_expectingMetaStateName ()\r
+{\r
+  llassert (!expectingMetaStateName);\r
+  llassert (context_inFunctionHeader ());\r
+  expectingMetaStateName = TRUE;\r
+}\r
+\r
+void cscanner_clearExpectingMetaStateName ()\r
+{\r
+  llassert (expectingMetaStateName);\r
+  expectingMetaStateName = FALSE;\r
+}\r
diff --git a/src/lclint.def b/src/lclint.def
new file mode 100644 (file)
index 0000000..ed03016
--- /dev/null
@@ -0,0 +1,4 @@
+NAME lclint WINDOWCOMPAT
+DESCRIPTION 'C source code checker'
+PROTMODE
+STACKSIZE 0x30000
diff --git a/test/Makefile-test.os2 b/test/Makefile-test.os2
new file mode 100644 (file)
index 0000000..4451498
--- /dev/null
@@ -0,0 +1,694 @@
+##################################################\r
+###                                            ###\r
+### Makefile for LCLint testing                ###\r
+###                                            ### \r
+### designed for use with GNU make             ### \r
+###                                            ###\r
+##################################################\r
+\r
+.PHONY: all fulltest quicktest funcpointer cast abstract\r
+.PHONY:        version help abstptr abstract alias alttypes ansireserved \r
+.PHONY: argorder blocks break cases cast charlit \r
+.PHONY: clauses commentchar \r
+.PHONY: compdestroy constannot controldepth csyntax czechnames czechoslovaknames \r
+.PHONY: deadparam decl enum exports external fields fileio flags forbody format funcpointer glob globals \r
+.PHONY: impabstract init inparam internal iter keep libs lintcomments \r
+.PHONY: list macros macrosef merge mergestate modifies modtest moduncon mongoincludes \r
+.PHONY: noeffect null observer oldstyle outglob outparam postnotnull preds prefixes printflike rc \r
+.PHONY: refcounts release repexpose returned sharing slovaknames special\r
+.PHONY: specclauses stack staticarray \r
+.PHONY: strings structassign nullret\r
+.PHONY: tainted typequals ud ulstypes union unreachable unused ullint unsignedcompare void\r
+.PHONY: db1 db2 db3 tests2.2 tests2.2a tests2.4 tests2.5\r
+.PHONY: all test fulltest expects quicktest\r
+.PHONY: warnuse metastate\r
+.PHONY: linked freearray\r
+.PHONY: sizeoftest\r
+.PHONY: bufferTest\r
+.PHONY: simplebufferConstraintTests\r
+.PHONY: moreBufferTests\r
+.PHONY: maxset\r
+.PHONY: globalbufferannotation\r
+.PHONY: strchr\r
+.PHONY: for\r
+\r
+.SUFFIXES: .out .expect .c .lcl .h .lh .diff\r
+\r
+# Command to run lclint\r
+LCLINT  = ..\\bin\\lclint\r
+LCLINTP = $(LCLINT)\r
+\r
+# Make sure .lclintrc files are not used so test results do not\r
+# depend on local settings.\r
+LCLINTRN = $(LCLINTP) -nof -hints -booltype "bool"\r
+LCLINTR = $(LCLINTRN) -exportlocal   +debugfcnconstraint \r
+\r
+UNITTESTS = \\r
+  fileio tainted mergestate metastate \\r
+  help sizeoftest bufferTest simplebufferConstraintTests \\r
+  moreBufferTests globalbufferannotation maxset strchr for \\r
+  abstptr abstract alias alttypes ansireserved argorder args blocks break cases cast \\r
+  charlit clauses commentchar compdestroy constannot controldepth csyntax czechnames czechoslovaknames deadparam \\r
+  decl enum exports external fields flags forbody format freearray funcpointer glob globals impabstract \\r
+  init inparam internal iter keep libs linked lintcomments list macros macrosef merge modifies \\r
+  modtest moduncon mongoincludes mystrncat noeffect null observer oldstyle \\r
+  outglob outparam postnotnull preds prefixes \\r
+  printflike rc refcounts release repexpose returned sharing slovaknames specclauses special stack \\r
+  staticarray strings structassign \\r
+  typequals ud ulstypes union unreachable unsignedcompare unused ullint void \\r
+  tests2.2 tests2.2a tests2.4 tests2.5 \r
+\r
+UNITEXPECTS  = $(addsuffix .expect, $(UNITTESTS))\r
+\r
+LCLINTTESTS = version $(UNITTESTS) \r
+\r
+all: quicktest\r
+\r
+DIFF = diff\r
+\r
+### not real .c\r
+\r
+quicktest: $(LCLINTTESTS)\r
+\r
+###\r
+### Unit Tests\r
+###\r
+\r
+version:\r
+       @$(LCLINTP) -help version\r
+       @$(LCLINTP) -help vars\r
+\r
+abstptr:\r
+       $(LCLINTR) abstptr -expect 9\r
+       $(LCLINTR) abstptr +voidabstract -expect 6\r
+\r
+abstract:\r
+       $(LCLINTR) abst_t.lcl commentcmd.c -expect 15\r
+\r
+alias:\r
+       $(LCLINTR) +lh mut\r
+       $(LCLINTR) mut alias +globalias -expect 19\r
+       $(LCLINTR) mut alias2 +globalias -expect 17\r
+       $(LCLINTR) +lh alias3 -expect 14 \r
+       $(LCLINTR) +lh alias4 +boolint\r
+       $(LCLINTR) alias4 -pred +retalias -expect 6\r
+       $(LCLINTR) +lh alias5 +memchecks -null -specundef -expect 5\r
+\r
+alttypes:\r
+       $(LCLINTR) alttypes.c -expect 2\r
+\r
+###\r
+### evans 2001-06-07 - updated nameCheck.c to reflect C9X.\r
+### Reports one new errors for ansireserved.c - wctomb is bad even as a local variable.\r
+###    (could be a macro?)\r
+### Reports 3 additional errors for +checks; no longer suppresses name errors in the\r
+###    presense of other errors.\r
+###\r
+\r
+ansireserved:\r
+       $(LCLINTR) ansireserved.c +ansireserved -nolib -expect 9\r
+       $(LCLINTR) ansireserved.c +ansireserved +ansireservedlocal -nolib -expect 11\r
+       $(LCLINTRN) ansireserved.c +checks -exportlocal -exportheadervar -exportheader -expect 12\r
+       $(LCLINTR) ansireserved2.c +ansireserved -expect 1\r
+\r
+argorder:\r
+       $(LCLINTR) argorder.c -expect 4\r
+       $(LCLINTR) argorder2  -expect 5\r
+       $(LCLINTR) argorder3.c -expect 8\r
+       $(LCLINTR) argorder4 -expect 9\r
+       $(LCLINTR) argorder4 -evalorder -expect 1\r
+       $(LCLINTR) argorder5.c +evalorderuncon -expect 3\r
+\r
+args:\r
+       $(LCLINTR) args -noeffect -expect 12\r
+\r
+blocks:\r
+       $(LCLINTR) blocks.c -expect 4\r
+       $(LCLINTR) blocks.c +ifblock +elseifcomplete -expect 7\r
+       $(LCLINTR) blocks.c -ifempty +whileempty +whileblock -expect 3\r
+       $(LCLINTR) blocks.c -ifempty +forempty +forblock -expect 3\r
+       $(LCLINTR) blocks.c +allempty -expect 6\r
+       $(LCLINTRN) blocks.c +strict -exportlocal +partial -exportheader -expect 11\r
+\r
+break:\r
+       $(LCLINTR) break.c -expect 4\r
+       $(LCLINTR) break.c +deepbreak -expect 6\r
+       $(LCLINTR) break.c +deepbreak -looploopbreak -expect 5\r
+\r
+cases: \r
+       $(LCLINTR) cases.c -expect 5\r
+       $(LCLINTR) cases2.c -expect 2\r
+       $(LCLINTRN) cases2.c +checks -exportlocal -exportheader -expect 3\r
+       $(LCLINTRN) cases2.c +checks -exportlocal -exportheader -branchstate -expect 3\r
+\r
+cast:\r
+       $(LCLINTR) cast -accessmodule -expect 20\r
+       $(LCLINTRN) cast2.c +checks -exportlocal -exportheader -expect 3\r
+\r
+### Two addition errors detected with 2.5 with -numliteral.\r
+\r
+charlit:\r
+       $(LCLINTR) +hints charlit.c -expect 4\r
+       $(LCLINTR) +hints -numliteral charlit.c -expect 6\r
+       $(LCLINTR) +hints charlit.c +charintliteral +ignoresigns\r
+\r
+clauses: \r
+       $(LCLINTR) clauses.c +memchecks -expect 4\r
+       $(LCLINTR) clauses2.c +memchecks \r
+       $(LCLINTR) clauses3.c +memchecks -expect 2\r
+       $(LCLINTR) clauses3.c +memchecks +unixlib -expect 3\r
+\r
+commentchar:\r
+       $(LCLINTR) commentchar.c -expect 4\r
+       $(LCLINTR) -commentchar '#' commentchar.c -expect 4\r
+\r
+controldepth:\r
+       $(LCLINTR) +hints -controlnestdepth 2 controldepth.c -expect 2\r
+       $(LCLINTR) +hints -controlnestdepth 1 controldepth.c -expect 2\r
+\r
+compdestroy:\r
+       $(LCLINTRN) compdestroy.c +checks -exportlocal -exportheader -expect 1\r
+       $(LCLINTRN) compdestroy.c +checks -exportlocal -exportheader +strictdestroy -expect 2\r
+       $(LCLINTRN) compdestroy.c +checks -exportlocal -exportheader +strictdestroy +strictusereleased -expect 3\r
+       $(LCLINTRN) compdestroy.c +strict +partial -exportheader -expect 3\r
+\r
+constannot:\r
+       ${LCLINTRN} constannot.c +arraybounds  -exportlocal -expect 2\r
+\r
+csyntax:\r
+       $(LCLINTR) +quiet -incondefs csyntax.c -expect 1 \r
+       $(LCLINTR) +quiet csyntax2.c -expect 2\r
+       $(LCLINTR) +quiet csyntax3.c -expect 1\r
+       $(LCLINTR) +quiet -incondefs csyntax4.c\r
+       $(LCLINTR) +quiet csyntax5.c\r
+       $(LCLINTR) +quiet csyntax6.c\r
+       $(LCLINTR) +quiet csyntax7.c\r
+       $(LCLINTR) +quiet csyntax8.c\r
+       $(LCLINTR) +quiet csyntax9.c\r
+       $(LCLINTR) +quiet csyntax10.c\r
+       $(LCLINTR) +quiet csyntax11.c\r
+       $(LCLINTR) +quiet csyntax12.c\r
+       $(LCLINTR) +quiet csyntax13.c -expect 1\r
+       $(LCLINTR) +quiet csyntax14.c\r
+       $(LCLINTR) +quiet csyntax15.c\r
+       $(LCLINTR) +quiet csyntax16.c -expect 2\r
+       $(LCLINTR) +quiet csyntax17.c -expect 3\r
+\r
+czechnames:\r
+       $(LCLINTR) czechnames.c\r
+       $(LCLINTR) +hints +czech czechnames.c -expect 2\r
+       $(LCLINTR) +hints +czech -czechvars czechnames.c -expect 1\r
+       $(LCLINTR) +hints +czech -accessczech czechnames.c -expect 6\r
+\r
+czechoslovaknames:\r
+       $(LCLINTR) +hints +czechoslovak czechnames.c -expect 1\r
+       $(LCLINTR) +hints +czechoslovak slovaknames.c -expect 1\r
+       $(LCLINTR) +hints +czechoslovak +slovakvars slovaknames.c -expect 2\r
+\r
+###\r
+### deadparam added 2001-05-27\r
+###\r
+\r
+deadparam:\r
+       ${LCLINTR} deadparam.c -expect 3\r
+\r
+#\r
+# Was expect 3 before 2.4.  Earlier versions did not handle implicit\r
+# function pointers correctly.\r
+#\r
+\r
+decl:\r
+       $(LCLINTR) decl.c -expect 2\r
+       $(LCLINTRN) decl.c +strict -exportlocal -expect 5\r
+       $(LCLINTR) decl2 -expect 4\r
+\r
+enum:\r
+       $(LCLINTR) enum -expect 16\r
+       $(LCLINTR) enum -misscase -expect 14\r
+\r
+exports:\r
+       $(LCLINTR) exports.c +exporttype +exportvar +exportfcn +topuse +typeuse -expect 6\r
+       $(LCLINTR) exports.c +exportany -expect 3\r
+       $(LCLINTR) exports.c\r
+\r
+external:\r
+       $(LCLINTR) external.c +partial\r
+       $(LCLINTR) external.c +partial +distinctexternalnames -expect 2\r
+       $(LCLINTR) external.c -nolib +partial -externalnamelength 3 -expect 3\r
+       $(LCLINTR) external.c -nolib +partial -externalnamelength 3 +externalnamecaseinsensitive -expect 3\r
+       $(LCLINTR) external.c +partial -externalnamelength 3 -expect 4\r
+\r
+fields:\r
+       $(LCLINTR) fields.c +memchecks -expect 6\r
+       $(LCLINTR) fields2.c +memchecks -expect 5\r
+       $(LCLINTR) fields3.c +memchecks\r
+\r
+flags:\r
+       $(LCLINTR) flags.c -expect 8\r
+       $(LCLINTR) +nocomments flags.c -expect 2\r
+\r
+### Added 2001-06-02\r
+\r
+forbody:\r
+       ${LCLINTR} forbody.c -expect 2\r
+\r
+### Added 2001-06-03\r
+format:\r
+       ${LCLINTR} format.c -expect 3\r
+       ${LCLINTR} format.c -formatconst \r
+\r
+# two new errors (invalid lhs)\r
+\r
+funcpointer:\r
+       $(LCLINTR) +memchecks +noparams funcpointer.c -expect 18\r
+\r
+glob:\r
+       $(LCLINTR) glob -expect 4\r
+       $(LCLINTR) glob -globuse -expect 3\r
+       $(LCLINTR) glob +globunspec -expect 6\r
+\r
+globals:\r
+       $(LCLINTR) -modifies globals.c -expect 5\r
+       $(LCLINTR) -modifies globals.c +allglobals -expect 6\r
+       $(LCLINTR) -modifies globals.c +impcheckedglobals -expect 6\r
+       $(LCLINTR) -modifies globals.c -globals -checkstrictglobals -expect 2\r
+       $(LCLINTR) -modifies globals.c +globunspec -expect 6\r
+       $(LCLINTR) -modifies globals.c +globunspec +allglobals -expect 8\r
+\r
+# Was -accessfile\r
+impabstract: \r
+       $(LCLINTR) -accessmodule impabstract.c \r
+       $(LCLINTR) -accessmodule +hints +impabstract impabstract.c -expect 2\r
+       $(LCLINTR) -accessmodule +hints +impabstract impabstract -expect 4\r
+\r
+init:\r
+       $(LCLINTR) init.c -expect 12\r
+       $(LCLINTRN) init.c +checks -exportlocal -exportheadervar -expect 15\r
+\r
+inparam:\r
+       $(LCLINTR) inparam.c -expect 2\r
+       $(LCLINTR) +impouts inparam.c -expect 1\r
+\r
+internal:\r
+       $(LCLINTR) internal.c -expect 1\r
+       $(LCLINTR) internal.c +distinctinternalnames -expect 2\r
+       $(LCLINTR) internal.c -internalnamelen 28 -expect 3\r
+       $(LCLINTR) internal.c +internalnamecaseinsensitive -expect 3\r
+       $(LCLINTR) internal.c +internalnamecaseinsensitive +internalnamelookalike -expect 11\r
+\r
+###\r
+### iter\r
+### 2001-06-06: Error message for iter.lcl:3,6 fixed to iter.lcl:3:6\r
+### \r
+\r
+iter:\r
+       $(LCLINTR) iter -expect 14 -lclexpect 1\r
+       $(LCLINTR) iter2.c -expect 12\r
+\r
+keep:\r
+       $(LCLINTR) keep.c +memchecks -expect 6\r
+\r
+### libs\r
+### 2001-05-22: 2 new errors found (fixed spec of signal)\r
+### 2001-05-30: 3 new errors found (formatconst)\r
+\r
+libs:\r
+       $(LCLINTR) libs.c +longunsignedunsignedintegral -expect 18\r
+       $(LCLINTR) libs.c -expect 22\r
+       $(LCLINTR) libs.c +globunspec +modunspec -expect 25\r
+       $(LCLINTR) libs.c +strictlib +globunspec +modunspec -expect 42\r
+\r
+lintcomments:\r
+       $(LCLINTR) lintcomments.c -expect 4\r
+       $(LCLINTR) lintcomments.c -warnlintcomments -expect 1\r
+       $(LCLINTR) lintcomments.c -lintcomments -expect 4\r
+\r
+list:\r
+       $(LCLINTR) list.c -expect 3\r
+\r
+macros:\r
+       $(LCLINTR) macros -expect 17 \r
+       $(LCLINTR) macros.c +allmacros -expect 34\r
+       $(LCLINTR) macros.c +fcnmacros -expect 31\r
+\r
+\r
+macrosef:\r
+       $(LCLINTR) macrosef -expect 4\r
+       $(LCLINTR) macrosef.c +allmacros -expect 3\r
+       $(LCLINTR) macrosef.c +allmacros +sefuncon -expect 4\r
+\r
+merge:\r
+       $(LCLINTRN) merge.c +checks -exportlocal -exportheadervar -exportheader -expect 3\r
+\r
+modifies:\r
+       $(LCLINTR) modifies.c modclient.c +impcheckedstatics +mustmod -expect 7\r
+\r
+modtest:\r
+       $(LCLINTR) modtest -expect 10\r
+       $(LCLINTR) modtest +modunspec -expect 13\r
+       $(LCLINTR) modtest +mustmod -expect 14\r
+\r
+moduncon:\r
+       $(LCLINTR) moduncon.c +moduncon -memchecks -expect 4\r
+       $(LCLINTRN) moduncon.c +strict -exportlocal -expect 22\r
+\r
+mongoincludes:\r
+       $(LCLINTR) mongoincludes.c -includenest 1 -expect 19\r
+       $(LCLINTR) mongoincludes.c -includenest 2 -expect 10\r
+       $(LCLINTR) mongoincludes.c -includenest 3 -expect 4\r
+       $(LCLINTR) mongoincludes.c -includenest 4 -expect 1\r
+       $(LCLINTR) mongoincludes.c -includenest 5 -expect 0\r
+\r
+mystrncat:\r
+       $(LCLINTR) mystrncat.c +arraybounds  +arrayboundsread -expect 4 \r
+\r
+noeffect:\r
+       ${LCLINT} -nof noeffect.c +allmacros +checks -expect 3\r
+\r
+null: \r
+       $(LCLINTR) null1.c -expect 14\r
+       $(LCLINTR) null1.c -null -expect 4\r
+       $(LCLINTR) null2.c -expect 10\r
+       $(LCLINTR) null3.c -expect 15\r
+       $(LCLINTR) null3.c -warnunixlib +unixlib -expect 16\r
+       $(LCLINTR) null4.c -expect 1\r
+       $(LCLINTR) null5.c -expect 4\r
+       $(LCLINTR) null6 -expect 4\r
+       $(LCLINTR) +quiet null6.lcl -dump null6\r
+       $(LCLINTR) null6.c -load null6 -expect 4\r
+\r
+### Added for 3.0 (bugs reported by Kevin Broady)\r
+\r
+nullret:\r
+       $(LCLINTR) nullret.c -expect 2\r
+       $(LCLINTR) -nullret nullret.c -expect 1\r
+\r
+nullassign:\r
+       $(LCLINTR) nullassign.c -expect 2\r
+       $(LCLINTR) -nullassign nullassign.c -expect 1\r
+\r
+\r
+#\r
+# Before 2.4, expected one more because error was reported both as \r
+# dependent and observer.\r
+#\r
+\r
+observer:\r
+       $(LCLINTRN) observer +checks -exportlocal -exportheader -expect 9\r
+       $(LCLINTRN) observer.c +checks -exportlocal -exportheader -expect 8\r
+       $(LCLINTR) observer.c -expect 7\r
+\r
+oldstyle:\r
+       $(LCLINTR) oldstyle -expect 3\r
+\r
+outglob:\r
+       $(LCLINTR) outglob -expect 10\r
+\r
+outparam:\r
+       $(LCLINTR) outparam -expect 12\r
+\r
+### evans 2001-08-26: postnotnull new\r
+\r
+postnotnull:\r
+       ${LCLINTR} postnotnull.c -expect 1\r
+#\r
+# Four new +fcnuse errors for -strict (evans 2001-07-22)\r
+# \r
+\r
+preds:\r
+       $(LCLINTR) +hints preds.c -expect 6\r
+       $(LCLINTRN) +hints preds.c -weak -expect 1\r
+       $(LCLINTRN) +hints preds.c -strict -exportlocal -exportheader -expect 12\r
+\r
+prefixes:\r
+       $(LCLINTR) prefixes.c +partial\r
+       $(LCLINTRN) prefixes.c +allmacros +checks -exportlocal +partial -exportheader -exportheadervar -expect 4\r
+       $(LCLINTR) prefixes.c -typeprefix "T" -expect 2\r
+       $(LCLINTR) prefixes.c -typeprefix "^" -expect 1\r
+       $(LCLINTR) prefixes.c -typeprefix "^*" -expect 2\r
+       $(LCLINTR) prefixes.c -typeprefix "^%*" -expect 2\r
+       $(LCLINTR) prefixes.c -typeprefix "^~*" -expect 2\r
+       $(LCLINTR) prefixes.c -typeprefix "^" +typeprefixexclude -expect 7\r
+       $(LCLINTR) prefixes.c -filestaticprefix "^^" -expect 4\r
+       $(LCLINTR) prefixes.c -filestaticprefix "^#" -expect 5\r
+       $(LCLINTR) prefixes.c -filestaticprefix "^?&x" -expect 5\r
+       $(LCLINTR) prefixes.c -globalprefix "G" -expect 1\r
+       $(LCLINTR) prefixes.c -globalprefix "&G?_^" -expect 1\r
+       $(LCLINTR) prefixes.c -externalprefix "G" -expect 5\r
+       $(LCLINTR) prefixes.c -typeprefix "T" -externalprefix "G" -expect 4\r
+\r
+# herbert: does not work (shell capabilities)\r
+#      $(LCLINTR) prefixes.c -localprefix "?*" +localprefixexclude -expect 13\r
+\r
+printflike:\r
+       $(LCLINTR) printflike.c -expect 6\r
+       $(LCLINTR) printflike.c -warnlintcomments -expect 5\r
+\r
+rc:\r
+       $(LCLINTR) -DMYSTERY=12 rc.c -expect 1\r
+       $(LCLINTR) -f rc1.lclintrc rc.c -expect 1\r
+       $(LCLINTR) -UMYSTERY -f rc1.lclintrc rc.c -expect 1\r
+       $(LCLINTR) -f rc3.lclintrc.os2 rc.c -expect 1\r
+\r
+refcounts:\r
+       $(LCLINTR) refcounts.c -expect 7 \r
+\r
+release:\r
+       $(LCLINTR) release.c +memchecks -expect 1\r
+\r
+repexpose:\r
+       $(LCLINTR) +lh repexpose +memchecks -expect 12\r
+       $(LCLINTR) repexpose +memchecks +retalias -expect 15\r
+       $(LCLINTRN) repexpose +checks -exportlocal -expect 27\r
+\r
+### returned added 2001-05-27\r
+### (Bug discovered checking lclint sources.)\r
+\r
+returned:\r
+       ${LCLINTR} returned.c -expect 1\r
+\r
+sharing: \r
+       $(LCLINTR) sharing1.c -expect 21\r
+       $(LCLINTR) sharing3.c -expect  3\r
+       $(LCLINTR) sharing4.c -expect 13\r
+       $(LCLINTR) sharing4.c -paramimptemp -expect 12\r
+       $(LCLINTR) sharing5.c -expect 6\r
+\r
+slovaknames:\r
+       $(LCLINTR) +hints slovaknames.c -expect 1\r
+       $(LCLINTR) +hints slovaknames.c +accessslovak \r
+       $(LCLINTR) +hints +slovak slovaknames.c -expect 3\r
+       $(LCLINTR) +hints +slovak -slovakvars slovaknames.c -expect 2\r
+       $(LCLINTR) +hints +slovak -accessslovak slovaknames.c -expect 7\r
+\r
+specclauses:\r
+       $(LCLINTR) specclauses.c -expect 6\r
+       $(LCLINTR) specclauses2.c -expect 8\r
+       $(LCLINTR) specclauses3.c -expect 6\r
+       $(LCLINTR) specclauses4.c -expect 3\r
+       $(LCLINTR) specclauses5.c -expect 3\r
+\r
+special:\r
+       $(LCLINTR) special -expect 20\r
+       $(LCLINTR) special -relaxquals -expect 22\r
+\r
+stack:\r
+       $(LCLINTR) stack.c -expect 5\r
+       $(LCLINTR) stack.c -stackref\r
+\r
+staticarray:\r
+       $(LCLINTR) staticarray.c -expect 3\r
+\r
+strings:\r
+       $(LCLINTR) strings.c -expect 3\r
+       $(LCLINTR) -readonlystrings -expect 1 strings.c\r
+       $(LCLINTR) +modobserverstrict -maintype -expect 4 strings.c\r
+\r
+structassign:\r
+       $(LCLINTR) structassign.c -expect 4\r
+\r
+typequals:\r
+       $(LCLINTR) typequals.c tq.lcl -expect 5\r
+       $(LCLINTR) typequals.c -expect 2\r
+\r
+ud:\r
+       $(LCLINTR) ud.c -expect 9\r
+       $(LCLINTR) ud2 -specundef -expect 3\r
+\r
+ulstypes:\r
+       $(LCLINTR) ulstypes.c -expect 8\r
+       $(LCLINTR) ulstypes.c +ignorequals \r
+       $(LCLINTRN) ulstypes.c +strict -exportheader -exportheadervar -expect 28\r
+# 3 more detected with version 2.5 (change in -numliteral setting)\r
+\r
+union:\r
+       $(LCLINTR) +memchecks union.c -expect 8\r
+\r
+unreachable:\r
+       $(LCLINTR) unreachable.c -expect 5\r
+       $(LCLINTR) -unreachable unreachable.c -expect 2\r
+       $(LCLINTR) switch.c -expect 4\r
+\r
+unsignedcompare:\r
+       ${LCLINT} +posixlib unsignedcompare.c -expect 2\r
+\r
+\r
+###\r
+### 2001-06-08 evans: 2 new errors after fixing ansireserved name checks\r
+###\r
+\r
+unused:\r
+       $(LCLINTRN) unused.c +checks -exportlocal -expect 5\r
+       $(LCLINTRN) unused.c +checks -exportlocal +topuse -expect 8\r
+\r
+###\r
+### 2001-06-10: Provided by Jim Zalenka\r
+###\r
+\r
+ullint:\r
+       ${LCLINTRN} ullint.c -expect 5\r
+       ${LCLINTRN} ullint.c +charint +charintliteral -expect 2\r
+\r
+void:\r
+       ${LCLINTRN} void.c -expect 2\r
+\r
+###\r
+### New since 2.5q:\r
+###\r
+\r
+linked:\r
+       ${LCLINTR} linked.c -expect 4\r
+       ${LCLINTR} linked2.c -expect 3\r
+       ${LCLINTR} linked3.c -expect 5\r
+       ${LCLINTR} linked4.c -expect 6\r
+       ${LCLINTR} linked5.c -expect 4\r
+       ${LCLINTR} linked6.c -expect 4\r
+\r
+freearray:\r
+       ${LCLINTR} freearray.c -expect 1\r
+\r
+###\r
+### Bugs fixed and new features since version 2.1b\r
+###\r
+\r
+tests2.2:\r
+       @echo "  Note: expect difference in name of unclosed file."\r
+       $(MAKE) -C tests2.2 -f Makefile-tests2.2.os2 LCLINT="$(LCLINTR)"\r
+\r
+tests2.4:\r
+       $(MAKE) -C tests2.4 -f Makefile-tests2.4.os2 LCLINT="$(LCLINTR)"\r
+\r
+tests2.5:\r
+       $(MAKE) -C tests2.5 LCLINT="$(LCLINTR)"\r
+\r
+sizeoftest:\r
+       @cd sizeoftest ; \\r
+       $(LCLINTR) +arraybounds  +arrayboundsread sizeof.c\r
+\r
+bufferTest:\r
+       @cd bufferTest ; \\r
+       $(LCLINTR) +arraybounds  +arrayboundsread test4.c test6.c\r
+\r
+simplebufferConstraintTests:\r
+       @cd simplebufferConstraintTests ; \\r
+       $(LCLINTR) +arraybounds  +arrayboundsread m.c  sizeof.c  test3.c  test7.c\r
+\r
+moreBufferTests:\r
+       @cd moreBufferTests ; \\r
+       $(LCLINTR) +arraybounds  +arrayboundsread  unrecogCall.c strrchr.c initialization.c simplifyTest.c strncatNotReallyGood.c strncatReallyGood.c\r
+\r
+maxset:\r
+       @cd maxset ; \\r
+       $(LCLINTR) +arraybounds maxsetannotations.c; \\r
+       $(LCLINTR) +arraybounds maxsetnoannotations.c -expect 1\r
+\r
+globalbufferannotation:\r
+       @cd globalbufferannotation ; \\r
+       $(LCLINTR) +arraybounds  +arrayboundsread globalvariable.c\r
+\r
+strchr:\r
+       @cd strchr ; \\r
+       $(LCLINTR) +arraybounds +arrayboundsread  strchr.c -expect 2\r
+\r
+for:\r
+       @cd for ; \\r
+       $(LCLINTR)  +arraybounds  +arrayboundsread  for.c\r
+\r
+metastate:\r
+       @cd metastate ; \\r
+       $(LCLINTR) -mts file file1.c -expect 4; \\r
+       $(LCLINTR) -mts file file2.c -varuse -fcnuse -expect 2; \\r
+       $(LCLINTR) -mts file file3.c -varuse -fcnuse -expect 2; \\r
+       $(LCLINTR) -mts file file4.c -varuse -fcnuse -exportlocal -expect 1 ; \\r
+       $(LCLINTR) -mts file file5.c -varuse -fcnuse -exportlocal -expect 4; \\r
+       $(LCLINTR) -mts file file6.c -varuse -fcnuse -exportlocal -expect 2; \\r
+       $(LCLINTR) -mts file filebad.c -expect 3; \\r
+       $(LCLINTR) sockets.mts sockets.c -expect 3; \\r
+       $(LCLINTR) sockets.mts sockets2.c -expect 2; \\r
+       $(LCLINTR) -mts file struct.c -expect 1; \\r
+       $(LCLINTR) -mts file nullbranch.c -expect 2; \\r
+       $(LCLINTR) -mts file osd.c -expect 2\r
+\r
+mergestate:\r
+       @cd mergestate ; \\r
+       $(LCLINTR) -mts taintednm taintednm.c -mustfree -exportlocal -expect 2; \\r
+       $(LCLINTR) -mts tainted taintednm.c -mustfree -exportlocal -expect 4\r
+\r
+tainted:\r
+       @cd mergestate ; \\r
+       $(LCLINTR) -mts tainted tainted.c -mustfree -exportlocal -expect 4; \\r
+       $(LCLINTR) tainted-bad.mts tainted.xh tainted.c -mustfree -exportlocal -expect 9; \\r
+       $(LCLINTR) -mts tainted tainted2.c -mustfree -exportlocal -expect 1; \\r
+       $(LCLINTR) -mts tainted tainted3.c -mustfree -exportlocal -expect 1; \\r
+       $(LCLINTR) -mts tainted tainted4.c -mustfree -exportlocal -expect 1; \\r
+       $(LCLINTR) -mts tainted tainted5.c -mustfree -exportlocal; \\r
+       $(LCLINTR) -mts tainted taintedmerge.c -mustfree -exportlocal -expect 3; \\r
+       $(LCLINTR) -mts tainted taintedimplicit.c -mustfree -exportlocal -expect 1; \\r
+       $(LCLINTR) -mts tainted sprintf.c -expect 2\r
+\r
+fileio:\r
+       @cd fileio ; \\r
+       $(LCLINTR) -mts file -mts filerw filerw.c -expect 3; \\r
+       $(LCLINTR) -mts file -mts filerw file.c -expect 3; \\r
+       $(LCLINTR) -mts file filebranch.c\r
+\r
+warnuse:\r
+       @cd warnuse; \\r
+       $(LCLINTR) warnuse.c -expect 4; \\r
+       $(LCLINTR) warnuse.c -warnuse -expect 1; \\r
+       $(LCLINTR) warnuse.c -warnuse +bufferoverflow -expect 1; \\r
+       $(LCLINTR) warnuse.c -bufferoverflow -expect 2; \\r
+       $(LCLINTR) warngets.c -expect 1\r
+\r
+ensuresclauses:\r
+       @cd ensuresclauses ; \\r
+       ${LCLINT} ensures.c +fcnconstraint\r
+\r
+\r
+###\r
+### Integration Tests\r
+###\r
+\r
+db1:\r
+       setenv LCLINT '$(LCLINTRN)'; cd db1; $(MAKE) -e test\r
+\r
+\r
+### evans 2000-12-22\r
+### 2 errors are no longer reported, since eref is immutable.\r
+### Need to clarify what it means for an object to be immutable;\r
+### there should be 2 types with different storage requirements.\r
+\r
+db2:\r
+       setenv LCLINT '$(LCLINTRN)'; cd db2; $(MAKE) -e test\r
+\r
+db3:\r
+       setenv LCLINT '$(LCLINTRN)'; cd db3; $(MAKE) -e test\r
+\r
+clean:\r
+       -rm -f *~ #*# *.o *.lcs a.out \r
+       -cd db1 ; $(MAKE) clean\r
+       -cd db2 ; $(MAKE) clean\r
+       -cd db3 ; $(MAKE) clean\r
+\r
+\r
+\r
diff --git a/test/rc3.lclintrc.os2 b/test/rc3.lclintrc.os2
new file mode 100644 (file)
index 0000000..a48b231
--- /dev/null
@@ -0,0 +1,6 @@
+-externalnamelen               23
+internalnamelen        73
++tmpdir \spool\
+-tmpdir \spool
+                  -dump
+  
diff --git a/test/tests2.2/Makefile-tests2.2.os2 b/test/tests2.2/Makefile-tests2.2.os2
new file mode 100644 (file)
index 0000000..8f6f70a
--- /dev/null
@@ -0,0 +1,50 @@
+.PHONY: boolops bool boolenum break bstring decl enumbool extension modarray nestext offestof sizeofarray rex struct\r
+\r
+LCLINT = lclint\r
+\r
+all: boolops bool boolenum break bstring decl enumbool extension modarray nestext offestof sizeofarray rex struct\r
+\r
+boolops:\r
+       $(LCLINT) boolops.c -expect 1\r
+\r
+bool:\r
+       $(LCLINT) bool.lcl booldef.c -expect 1\r
+\r
+boolenum:\r
+       $(LCLINT) boolenum.c -booltype BOOLEAN -expect 1 \r
+\r
+break:\r
+       $(LCLINT) break.c -expect 1\r
+\r
+bstring:\r
+       $(LCLINT) bstring.c -expect 2 \r
+\r
+decl:\r
+       $(LCLINT) decl.c -expect 1 \r
+\r
+enumbool:\r
+       $(LCLINT) enumbool.c -expect 3 \r
+       $(LCLINT) enumbool.c -booltype "bool" -booltrue "true" -boolfalse "false" \r
+\r
+extension:\r
+       -$(LCLINT) extension.c\r
+       -$(LCLINT) -gnuextensions extension.c \r
+\r
+modarray:\r
+       $(LCLINT) modarray.c\r
+\r
+nestext:\r
+       $(LCLINT) nestext.c -expect 1\r
+\r
+offsetof:\r
+       $(LCLINT) offsetof.c\r
+\r
+sizeofarray:\r
+       $(LCLINT) sizeofarray.c -expect 3 \r
+\r
+rex:\r
+       $(LCLINT) rex.c -expect 4\r
+### 3 new errors reported\r
+\r
+struct:\r
+       $(LCLINT) struct.c -expect 1\r
diff --git a/test/tests2.4/Makefile-tests2.4.os2 b/test/tests2.4/Makefile-tests2.4.os2
new file mode 100644 (file)
index 0000000..ea99f56
--- /dev/null
@@ -0,0 +1,78 @@
+.PHONY: emptycase enumtest duffs bitfields bugs tests hexconstants innercomment nothing offsetof komazi print syslog error ulrich cpptest longlong subdir fink driverstub alignof source emptycase enumtest duffs bitfields bugs tests hexconstants innercomment nothing offsetof komazi print syslog error ulrich cpptest longlong subdir fink driverstub alignof source\r
+\r
+LCLINT = lclint\r
+\r
+all: emptycase enumtest duffs bitfields bugs tests hexconstants innercomment nothing offsetof komazi print syslog ulrich cpptest longlong subdir fink alignof source \r
+#error driverstub \r
+\r
+emptycase:\r
+       $(LCLINT) emptycase.c \r
+\r
+enumtest:\r
+       $(LCLINT) enumtest.c -expect 2\r
+\r
+duffs:\r
+       $(LCLINT) duffs.c -expect 7\r
+\r
+bitfields:\r
+       $(LCLINT) bitfields.c\r
+\r
+bugs:\r
+       $(LCLINT) bug1.c \r
+       $(LCLINT) bug2.c -expect 5 \r
+       $(LCLINT) bug3.c -expect 3\r
+\r
+tests:\r
+       $(LCLINT) test0.c \r
+       $(LCLINT) test1.c \r
+       $(LCLINT) test2.c \r
+\r
+hexconstants:\r
+       $(LCLINT) hexconstants.c -expect 1 \r
+       $(LCLINT) +checks hexconstants.c -expect 4\r
+\r
+innercomment:\r
+       $(LCLINT) innercomment.c -expect 2 +forcehints \r
+       $(LCLINT) innercomment.c -nestcomment\r
+\r
+nothing:\r
+       $(LCLINT) nothing.c \r
+\r
+offsetof:\r
+       $(LCLINT) offsetof.c -expect 2 \r
+\r
+komazi:\r
+       $(LCLINT) komazi.c \r
+\r
+print:\r
+       $(LCLINT) print.c \r
+\r
+syslog:\r
+       $(LCLINT) syslog.c -warnunixlib +unixlib \r
+\r
+#error:\r
+#      $(LCLINT) error.c -expect 1 \r
+\r
+ulrich:\r
+       $(LCLINT) ulrich.c -expect 1\r
+\r
+cpptest:\r
+       $(LCLINT) cpptest.c '-D__P(x)=x' -expect 1\r
+\r
+longlong:\r
+       $(LCLINT) longlong.c -expect 4\r
+\r
+subdir:\r
+       $(LCLINT) subdir/main.c subdir/main.lcl\r
+\r
+fink:\r
+       $(LCLINT) fink.c \r
+\r
+driverstub:\r
+       $(LCLINT) driverstub.c\r
+\r
+alignof:\r
+       $(LCLINT) alignof.c -expect 2\r
+\r
+source:\r
+       $(LCLINT) -D DBL_MANT_DIG=25 source.c\r
This page took 1.481192 seconds and 5 git commands to generate.