summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-02-29 04:15:25 +0000
committeriliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-02-29 04:15:25 +0000
commit64852889448800ceea68fdb2d85e1fbed986336a (patch)
tree3f577bf8bff93eae43fdec699b57bf93358919be
parente9814140b1dc31f263502ea79229a807a5ac43db (diff)
downloadATCD-64852889448800ceea68fdb2d85e1fbed986336a.tar.gz
Merged revisions 80741,80751-80752,80754,80761,80763,80770,80773 via svnmerge from
https://svn.dre.vanderbilt.edu/DOC/Middleware/trunk/TAO ........ r80741 | sowayaa | 2008-02-26 10:18:03 -0600 (Tue, 26 Feb 2008) | 2 lines Tue Feb 26 16:16:16 UTC 2008 Abdullah Sowayan <abdullah.sowayan@lmco.com> ........ r80751 | johnnyw | 2008-02-27 02:37:10 -0600 (Wed, 27 Feb 2008) | 1 line Wed Feb 27 08:36:37 UTC 2008 Johnny Willemsen <jwillemsen@remedy.nl> ........ r80752 | johnnyw | 2008-02-27 05:20:42 -0600 (Wed, 27 Feb 2008) | 1 line ........ r80754 | sowayaa | 2008-02-27 09:24:53 -0600 (Wed, 27 Feb 2008) | 2 lines Wed Feb 27 15:21:48 UTC 2008 Abdullah Sowayan <abdullah.sowayan@lmco.com> ........ r80761 | wotte | 2008-02-27 14:01:34 -0600 (Wed, 27 Feb 2008) | 1 line ChangeLogTag:Wed Feb 27 19:24:02 UTC 2008 William R. Otte <wotte@dre.vanderbilt.edu> ........ r80763 | sutambe | 2008-02-28 00:06:08 -0600 (Thu, 28 Feb 2008) | 1 line Thu Feb 28 06:01:19 UTC 2008 Sumant Tambe <sutambe@nospam> ........ r80770 | wotte | 2008-02-28 07:27:00 -0600 (Thu, 28 Feb 2008) | 1 line ChangeLogTag:Thu Feb 28 13:26:12 UTC 2008 William R. Otte <wotte@dre.vanderbilt.edu> ........ r80773 | parsons | 2008-02-28 13:21:47 -0600 (Thu, 28 Feb 2008) | 1 line ChangeLogTag: Thu Feb 28 19:16:43 UTC 2008 Jeff Parsons <j.parsons@vanderbilt.edu> ........
-rw-r--r--TAO/ChangeLog135
-rw-r--r--TAO/MPC/config/mcpp.mpb5
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/LICENSE29
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/Makefile.am40
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/cc1.cpp61
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/configed.H370
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/directive.cpp1520
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/eval.cpp1669
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/expand.cpp1584
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/internal.H512
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/lib.cpp130
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/main.cpp1128
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/mbchar.cpp766
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/mcpp.mpc41
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/mcpp_lib.cpp7
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/mcpp_lib.h29
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/mcpp_lib_export.h58
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/noconfig.H467
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/preproc.cpp9
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/support.cpp2577
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/system.H387
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/system.cpp3794
-rw-r--r--TAO/TAO_IDL/contrib/mcpp/testmain.cpp77
-rw-r--r--TAO/TAO_IDL/driver/drv_mcpp_preproc.cpp1120
-rw-r--r--TAO/TAO_IDL/preproc.mpb11
-rw-r--r--TAO/TAO_IDL/tao_idl.cpp2
-rw-r--r--TAO/TAO_IDL/tao_idl.mpc3
-rw-r--r--TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp2
-rw-r--r--TAO/orbsvcs/Notify_Service/NT_Notify_Server.cpp2
-rw-r--r--TAO/orbsvcs/examples/CosEC/Simple/Consumer.cpp2
-rw-r--r--TAO/orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc9
-rw-r--r--TAO/orbsvcs/examples/CosEC/Simple/Service.cpp2
-rw-r--r--TAO/orbsvcs/examples/CosEC/Simple/Supplier.cpp2
-rw-r--r--TAO/orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp2
-rw-r--r--TAO/orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc4
-rw-r--r--TAO/orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp2
-rw-r--r--TAO/orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc2
-rw-r--r--TAO/orbsvcs/examples/ImR/Combined_Service/test.cpp2
-rw-r--r--TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.cpp4
-rw-r--r--TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc12
-rw-r--r--TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc1
-rw-r--r--TAO/orbsvcs/examples/RtEC/Kokyu/Service.cpp4
-rw-r--r--TAO/orbsvcs/examples/RtEC/MCast/MCast.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc1
-rw-r--r--TAO/orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc1
-rw-r--r--TAO/orbsvcs/examples/RtEC/Schedule/Service.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/Simple/Consumer.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc9
-rw-r--r--TAO/orbsvcs/examples/RtEC/Simple/Service.cpp2
-rw-r--r--TAO/orbsvcs/examples/RtEC/Simple/Supplier.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/IFRService/ConstantDef_i.h44
-rw-r--r--TAO/orbsvcs/orbsvcs/IFRService/EnumDef_i.h25
-rw-r--r--TAO/orbsvcs/orbsvcs/IFRService/IFR_Service_Utils.cpp39
-rw-r--r--TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp2
-rw-r--r--TAO/orbsvcs/tests/Redundant_Naming/client.cpp2
-rw-r--r--TAO/orbsvcs/tests/Sched/DynSched_Test.cpp6
-rw-r--r--TAO/tao/GIOP_Message_Generator_Parser_12.cpp45
-rw-r--r--TAO/tao/Invocation_Base.cpp1
-rw-r--r--TAO/tao/LocalObject.h3
-rw-r--r--TAO/tao/TAO_Server_Request.cpp14
65 files changed, 16690 insertions, 105 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index c2113837244..368ff89f908 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,138 @@
+Thu Feb 28 19:16:43 UTC 2008 Jeff Parsons <j.parsons@vanderbilt.edu>
+
+ * orbsvcs/orbsvcs/IFRService/EnumDef_i.h:
+ * orbsvcs/orbsvcs/IFRService/ConstantDef_i.h:
+
+ Cosmetic changes.
+
+ * orbsvcs/orbsvcs/IFRService/IFR_Service_Utils.cpp:
+
+ Changed creation of IOR output file to use
+ ACE_DEFAULT_FILE_PERMS. Also added more error checking to
+ cover the open, write and close steps. Thanks to Jules
+ Colding <colding at 42tools dot com> for reporting that
+ the previous code created a file that was world writable.
+
+Thu Feb 28 13:26:12 UTC 2008 William R. Otte <wotte@dre.vanderbilt.edu>
+
+ * TAO_IDL/contrib/mcpp/eval.cpp:
+ * TAO_IDL/contrib/mcpp/expand.cpp:
+ * TAO_IDL/contrib/mcpp/mbchar.cpp:
+ * TAO_IDL/contrib/mcpp/mcpp.mpc:
+ * TAO_IDL/contrib/mcpp/support.cpp:
+ * TAO_IDL/contrib/mcpp/system.cpp:
+
+ Compile error fixes.
+
+Thu Feb 28 06:01:19 UTC 2008 Sumant Tambe <sutambe@nospam>
+
+ * TAO_IDL/contrib/mcpp/main.cpp:
+ * TAO_IDL/contrib/mcpp/support.cpp:
+ * TAO_IDL/contrib/mcpp/system.cpp:
+
+ #included OS_NS_stdlib.h header for ACE_OS::free,
+ ACE_OS::malloc, and ACE_OS::realloc.
+
+Wed Feb 27 19:24:02 UTC 2008 William R. Otte <wotte@dre.vanderbilt.edu>
+
+ * TAO_IDL/contrib/mcpp/LICENSE:
+ * TAO_IDL/contrib/mcpp/Makefile.am:
+ * TAO_IDL/contrib/mcpp/Makefile.in:
+ * TAO_IDL/contrib/mcpp/cc1.cpp:
+ * TAO_IDL/contrib/mcpp/config.h.in:
+ * TAO_IDL/contrib/mcpp/configed.H:
+ * TAO_IDL/contrib/mcpp/directive.cpp:
+ * TAO_IDL/contrib/mcpp/eval.cpp:
+ * TAO_IDL/contrib/mcpp/expand.cpp:
+ * TAO_IDL/contrib/mcpp/internal.H:
+ * TAO_IDL/contrib/mcpp/lib.cpp:
+ * TAO_IDL/contrib/mcpp/main.cpp:
+ * TAO_IDL/contrib/mcpp/mbchar.cpp:
+ * TAO_IDL/contrib/mcpp/mcpp.mpc:
+ * TAO_IDL/contrib/mcpp/mcpp_lib.h:
+ * TAO_IDL/contrib/mcpp/mcpp_lib.cpp:
+ * TAO_IDL/contrib/mcpp/mcpp_lib_export.h:
+ * TAO_IDL/contrib/mcpp/noconfig.H:
+ * TAO_IDL/contrib/mcpp/preproc.cpp:
+ * TAO_IDL/contrib/mcpp/support.cpp:
+ * TAO_IDL/contrib/mcpp/system.H:
+ * TAO_IDL/contrib/mcpp/system.cpp:
+ * TAO_IDL/contrib/mcpp/testmain.cpp:
+
+ An open source, BSD licensed C preprocessor.
+
+ * TAO_IDL/driver/drv_mcpp_preproc.cpp:
+
+ Derived from drv_preproc.cpp, invokes the MCPP preprocessor
+ as a library call instad of spawning a process.
+
+ * TAO_IDL/preproc.mpb:
+ * TAO_IDL/tao_idl.mpc:
+ * MPC/config/mcpp.mpb:
+
+ Modifications supporting selection of drv_preproc/drv_mcpp_preproc
+ based on the mcpp feature.
+
+Wed Feb 27 15:21:48 UTC 2008 Abdullah Sowayan <abdullah.sowayan@lmco.com>
+
+ * orbsvcs/Naming_Service/NT_Naming_Server.cpp:
+ * orbsvcs/Notify_Service/NT_Notify_Server.cpp:
+ * orbsvcs/examples/CosEC/Simple/Consumer.cpp:
+ * orbsvcs/examples/CosEC/Simple/Service.cpp:
+ * orbsvcs/examples/CosEC/Simple/Supplier.cpp:
+ * orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp:
+ * orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp:
+ * orbsvcs/examples/ImR/Combined_Service/test.cpp:
+ * orbsvcs/examples/Notify/Federation/Agent/Agent.cpp:
+ * orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp:
+ * orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp:
+ * orbsvcs/examples/RtEC/IIOPGateway/EC.cpp:
+ * orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp:
+ * orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp:
+ * orbsvcs/examples/RtEC/Kokyu/Service.cpp:
+ * orbsvcs/examples/RtEC/MCast/MCast.cpp:
+ * orbsvcs/examples/RtEC/Schedule/Service.cpp:
+ * orbsvcs/examples/RtEC/Simple/Consumer.cpp:
+ * orbsvcs/examples/RtEC/Simple/Service.cpp:
+ * orbsvcs/examples/RtEC/Simple/Supplier.cpp:
+ * orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp:
+ * orbsvcs/tests/Redundant_Naming/client.cpp:
+ * orbsvcs/tests/Sched/DynSched_Test.cpp:
+
+ Use ACE_TMAIN instead of main as the program entry point to comply
+ with ACE/TAO/CIAO coding standards.
+
+ * orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc:
+ * orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc:
+ * orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc:
+ * orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc:
+ * orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc:
+ * orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc:
+ * orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc:
+ * orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc:
+
+ MPC doesn't recognize ACE_TMAIN as an entry point, as such, we need
+ to explicitly set exename in the MPC file.
+
+Wed Feb 27 08:36:37 UTC 2008 Johnny Willemsen <jwillemsen@remedy.nl>
+
+ * tao/GIOP_Message_Generator_Parser_12.cpp:
+ Check the return value of operator<<
+
+ * tao/Invocation_Base.{cpp,inl}:
+ Moved a few methods to the inline file
+
+ * tao/LocalObject.h:
+ * tao/TAO_Server_Request.cpp:
+ Layout change
+
+Tue Feb 26 16:16:16 UTC 2008 Abdullah Sowayan <abdullah.sowayan@lmco.com>
+
+ * TAO_IDL/tao_idl.cpp:
+
+ Use ACE_TMAIN instead of main as the program entry point to comply
+ with ACE/TAO/CIAO coding standards.
+
Mon Feb 25 22:19:46 UTC 2008 Abdullah Sowayan <abdullah.sowayan@lmco.com>
* orbsvcs/examples/CosEC/Factory/FactoryClient.cpp:
diff --git a/TAO/MPC/config/mcpp.mpb b/TAO/MPC/config/mcpp.mpb
new file mode 100644
index 00000000000..96206ee1c7a
--- /dev/null
+++ b/TAO/MPC/config/mcpp.mpb
@@ -0,0 +1,5 @@
+feature(mcpp) {
+ after += TAO_IDL_MCPP
+ includes += $(TAO_ROOT)/TAO_IDL/contrib/mcpp
+ libs += TAO_IDL_MCPP
+} \ No newline at end of file
diff --git a/TAO/TAO_IDL/contrib/mcpp/LICENSE b/TAO/TAO_IDL/contrib/mcpp/LICENSE
new file mode 100644
index 00000000000..46ae24a3191
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/LICENSE
@@ -0,0 +1,29 @@
+/*-
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * This software including the files in this directory is provided under
+ * the following license.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/Makefile.am b/TAO/TAO_IDL/contrib/mcpp/Makefile.am
new file mode 100644
index 00000000000..e5ee591adc5
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/Makefile.am
@@ -0,0 +1,40 @@
+## Process this file with automake to produce Makefile.in
+
+if MCPP_LIB
+
+lib_LTLIBRARIES = libmcpp.la
+libmcpp_la_SOURCES = system.H configed.H internal.H main.c directive.c eval.c expand.c mbchar.c support.c system.c lib.c mcpp_lib.h
+libmcpp_la_LDFLAGS = -no-undefined -version-info 0:1:0
+
+main.lo directive.lo eval.lo expand.lo mbohar.lo support.lo system.lo : system.H internal.H mcpp_lib.h
+lib.lo : configed.H
+system.H : configed.H
+
+else
+
+bin_PROGRAMS = mcpp
+mcpp_SOURCES = system.H configed.H internal.H main.c directive.c eval.c expand.c mbchar.c support.c system.c lib.c mcpp_lib.h
+mcpp_CFLAGS = $(AM_CFLAGS) ## dummy to avoid conflict with MCPP_LIB
+
+main.o directive.o eval.o expand.o mbohar.o support.o system.o : system.H internal.H mcpp_lib.h
+lib.o : configed.H
+system.H : configed.H
+
+endif
+
+if REPLACE_CPP
+if GNUC
+
+if MINGW
+cc1_PROGRAMS = cc1
+cc1_SOURCES = cc1.c
+cc1dir = $(bindir)
+endif
+
+install-exec-hook:
+ @if test x"$(gcc_path)" = x""; then exit 1; fi
+ @$(srcdir)/set_mcpp.sh '$(gcc_path)' $(gcc_maj_ver) $(gcc_min_ver) '$(cpp_call)' '$(CC)' '$(CXX)' 'x$(EXEEXT)' '$(LN_S)' '$(inc_dir)'
+uninstall-hook:
+ @$(srcdir)/unset_mcpp.sh '$(gcc_path)' $(gcc_maj_ver) $(gcc_min_ver) '$(cpp_call)' '$(CC)' '$(CXX)' 'x$(EXEEXT)' '$(LN_S)' '$(inc_dir)'
+endif
+endif
diff --git a/TAO/TAO_IDL/contrib/mcpp/cc1.cpp b/TAO/TAO_IDL/contrib/mcpp/cc1.cpp
new file mode 100644
index 00000000000..1d623b4c3fe
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/cc1.cpp
@@ -0,0 +1,61 @@
+/*
+ * cc1.c: dummy cc1 and cc1plus to be invoked by MinGW's GCC
+ * MinGW's GCC does not invoke shell-script named cc1.
+ * $Id$
+ */
+
+#include "stdio.h"
+#include "string.h"
+#include "process.h"
+
+#define ARG_LIM 64
+
+int exec_program( int argc, char ** argv);
+
+int main( int argc, char ** argv) {
+ int status;
+
+ if (argc - 1 >= ARG_LIM) {
+ ACE_OS::fprintf( stderr, "Too many arguments.\n");
+ return 1;
+ }
+ status = exec_program( argc, argv);
+ /* MinGW does not have fork() nor wait(). */
+ return status;
+}
+
+int exec_program( int argc, char ** argv) {
+ char * buf[ ARG_LIM];
+ char temp[ FILENAME_MAX];
+ char * tp;
+ int plus = 0;
+ int n = 1;
+ int i;
+ int status;
+ size_t len;
+
+ if (ACE_OS::strstr( argv[ 0], "cc1plus"))
+ plus = 1; /* C++ */
+ tp = ACE_OS::strstr( argv[ 0], "cc1");
+ len = tp - argv[ 0];
+ ACE_OS::memcpy( temp, argv[ 0], len);
+ temp[ len] = '\0';
+ tp = temp + len;
+ for (i = 1; i < argc; i++)
+ if (ACE_OS::strcmp( argv[ i], "-fpreprocessed") == 0)
+ break; /* Invoke cc1 or cc1plus */
+ if (i < argc) {
+ ACE_OS::strcpy( tp, plus ? "cc1plus_gnuc.exe" : "cc1_gnuc.exe");
+ } else { /* Invoke mcpp */
+ ACE_OS::strcpy( tp, "mcpp.exe");
+ if (plus)
+ buf[ n++] = "-+"; /* Insert the option */
+ }
+ buf[ 0] = temp;
+ for (i = 1; i < argc; i++, n++)
+ buf[ n] = argv[ i];
+ buf[ n] = 0;
+
+ status = spawnv( _P_WAIT, buf[ 0], buf);
+ return status;
+}
diff --git a/TAO/TAO_IDL/contrib/mcpp/configed.H b/TAO/TAO_IDL/contrib/mcpp/configed.H
new file mode 100644
index 00000000000..22b27ecd348
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/configed.H
@@ -0,0 +1,370 @@
+/* $Id$
+ * configed.H
+ * Configurations for MCPP using config.h genarated by configure script.
+ *
+ * WARNING: These settings assume HOST == TARGET. In case of HOST
+ * differs from TARGET, you must edit this file here and there.
+ */
+
+#define TRUE 1
+#define FALSE 0
+#define DATE "2007/05" /* Date of mcpp */
+
+/*
+ * 'Target' means the O.S. and the compiler to which cpp is implemented.
+ * 'Host' means the O.S. and the compiler with which cpp is compiled.
+ */
+
+#include "config.h"
+
+#ifndef COMPILER /* No target compiler specified */
+#define COMPILER COMPILER_UNKNOWN
+#endif
+#ifndef HOST_COMPILER /* No host compiler specified */
+#define HOST_COMPILER COMPILER
+#endif
+
+/*
+ * P A R T 1 Configurations for target-operating-system
+ * and target-compiler.
+ */
+
+/*
+ * Names of the SYSTEM (i.e. target operating system). This is needed so that
+ * cpp can use appropriate filename conventions.
+ */
+#define SYS_UNKNOWN 0
+#define SYS_UNIX 0x1000
+#define SYS_LINUX 0x1800 /* (SYS_LINUX & 0xF000) == SYS_UNIX */
+#define SYS_FREEBSD 0x1A00 /* (SYS_FREEBSD & 0xF000) == SYS_UNIX */
+#define SYS_CYGWIN 0x1C00 /* (SYS_CYGWIN & 0xF000) == SYS_UNIX */
+#define SYS_MAC 0x6000
+#define SYS_WIN 0x7000
+#define SYS_WIN32 0x7400 /* (SYS_WIN32 & 0xF000) == SYS_WIN */
+#define SYS_MINGW 0x7C00 /* (SYS_MINGW & 0xF000) == SYS_WIN */
+
+/* COMPILER */
+#define COMPILER_UNKNOWN 0
+#define MSC 0x7400 /* Microsoft C, Visual C++ */
+#define BORLANDC 0x7440 /* Borland C */
+#define WIN_SYMANTECC 0x7470 /* Symantec for Windows */
+#define LCC 0x74C0 /* LCC-Win32 */
+#define GNUC 0x00E0 /* GNU C (GCC) */
+#define INDEPENDENT 0xFFFF /* No target, compiler-independent-build*/
+
+#define SYS_FAMILY (SYSTEM & 0xF000)
+#define COMPILER_FAMILY (COMPILER & 0xF0)
+#define HOST_SYS_FAMILY (HOST_SYSTEM & 0xF000)
+
+/* Default MBCHAR (multi-byte character) encoding. */
+#define EUC_JP 0x10 /* Extended UNIX code of JIS X 0208 */
+#define GB2312 0x20 /* EUC-like encoding of Chinese GB 2312-80 */
+#define KSC5601 0x30 /* EUC-like encoding of Korean KS C 5601 */
+#define SJIS 0x80 /* Shift-JIS encoding of JIS X 0208 */
+#define BIGFIVE 0x90 /* Encoding of Taiwanese Big Five */
+#define ISO2022_JP 0x100 /* ISO-2022-JP (ISO-2022-JP1) encoding */
+#define UTF8 0x1000 /* UTF-8 encoding */
+
+/*
+ * MBCHAR means multi-byte character encoding.
+ * MBCHAR means the default encoding, and you can change the encoding by
+ * #pragma MCPP setlocale, -e <encoding> option or environment variable
+ * LC_ALL, LC_CTYPE, LANG.
+ * MBCHAR == 0 means no multi-byte character encoding.
+ */
+
+/*
+ * In order to predefine target-dependent macros,
+ * several macros are defined here:
+ * *_OLD define the macro beginning with an alphabetic letter,
+ * *_STD, *_STD?, *_EXT, *_EXT2 define the macro beginning with an '_'.
+ * *_STD1 define the macro beginning with '__' and ending with an alpha-
+ * numeric letter.
+ * *_STD2 define the macro beginning with '__' and ending with '__'.
+ * These may not be defined, if they are not needed.
+ * They should not be #defined to no token or to "".
+ *
+ * CPU_OLD, CPU_STD1, CPU_STD2, CPU_SP_OLD, CPU_SP_STD
+ * define the target cpu (by name)
+ * SYSTEM_OLD, SYSTEM_STD1, SYSTEM_STD2, SYSTEM_EXT, SYSTEM_EXT2
+ * define the target operating system (by name)
+ * SYSTEM_SP_OLD, SYSTEM_SP_STD define the target-OS specific macro name
+ * COMPILER_OLD, COMPILER_STD1, COMPILER_STD2, COMPILER_EXT, COMPILER_EXT2
+ * , COMPILER_SP_OLD, COMPILER_SP_STD
+ * define the target compiler (by name)
+ * COMPILER_CPLUS define the target C++ compiler
+ * COMPILER_SP1, COMPILER_SP2, COMPILER_SP3
+ * define the compiler-specific macros
+ *
+ * <macro>_VAL specify the value of the <macro>.
+ * If not specified, these values default to "1".
+ * To define the value of no-token, specify as "" rather than no-token.
+ * CPU_*, SYSTEM_OLD, SYSTEM_STD?, COMPILER_OLD have the value of "1".
+ */
+
+/*
+ * target-compiler-dependent definitions:
+ *
+ * LINE_PREFIX defines the output line prefix, if not "#line 123".
+ * This should be defined as "# " to represent "# 123" format
+ * ("#line " represents "#line 123" format).
+ *
+ * ENV_C_INCLUDE_DIR may be defined to the name of environment-variable for
+ * C include directory.
+ * ENV_CPLUS_INCLUDE_DIR is name of environment-variable for C++ include
+ * directory which exists other than ENV_C_INCLUDE_DIR.
+ * ENV_SEP is the separator (other than space) of include-paths in an
+ * environment-variable. e.g. the ':' in
+ * "/usr/abc/include:/usr/xyz/include"
+ *
+ * EMFILE should be defined to the macro to represent errno of 'too many
+ * open files' if the macro is different from EMFILE.
+ *
+ * ONE_PASS should be set TRUE, if COMPILER is "one pass compiler".
+ *
+ * FNAME_FOLD means that target-system folds upper and lower cases of
+ * directory and file-name.
+ *
+ * SEARCH_INIT specifies the default value of 'search_rule' (in system.c).
+ * 'search_rule' holds searching rule of #include "header.h" to
+ * search first before searching user specified or system-
+ * specific include directories.
+ * CURRENT means to search the directory relative to "current
+ * directory" which is current at cpp invocation.
+ * SOURCE means to search the directory relative to that of the
+ * source file (i.e. "includer").
+ * (CURRENT & SOURCE) means to search current directory first
+ * source directory next.
+ * 'search_rule' is initialized to SEARCH_INIT.
+ */
+#define CURRENT 1
+#define SOURCE 2
+
+#if SYS_FAMILY == SYS_UNIX
+#define SYSTEM_OLD "unix"
+#define SYSTEM_STD1 "__unix"
+#define SYSTEM_STD2 "__unix__"
+#endif
+
+#if SYSTEM == SYS_FREEBSD
+#define SYSTEM_EXT "__FreeBSD__"
+#endif
+#if SYSTEM == SYS_LINUX
+#define SYSTEM_EXT "__linux__"
+#endif
+
+#if SYSTEM == SYS_CYGWIN
+#define SYSTEM_EXT "__CYGWIN__"
+#define SYSTEM_EXT2 "__CYGWIN32__"
+#ifndef MBCHAR
+#define MBCHAR SJIS
+#endif
+#endif
+
+#if SYSTEM == SYS_MINGW
+#define SYSTEM_EXT "__MINGW__"
+#define SYSTEM_EXT2 "__MINGW32__"
+#ifndef MBCHAR
+#define MBCHAR SJIS
+#endif
+#endif
+
+#if SYS_FAMILY == SYS_UNIX
+#ifndef MBCHAR
+#define MBCHAR EUC_JP
+#endif
+#endif
+
+#if COMPILER == GNUC
+#define COMPILER_EXT "__GNUC__"
+#define COMPILER_EXT_VAL GCC_MAJOR_VERSION
+#define COMPILER_EXT2 "__GNUC_MINOR__"
+#define COMPILER_EXT2_VAL GCC_MINOR_VERSION
+#define COMPILER_CPLUS "__GNUG__"
+#define COMPILER_CPLUS_VAL GCC_MAJOR_VERSION
+#ifndef ENV_C_INCLUDE_DIR
+#define ENV_C_INCLUDE_DIR "C_INCLUDE_PATH"
+#define ENV_CPLUS_INCLUDE_DIR "CPLUS_INCLUDE_PATH"
+#endif
+/*
+ * __SIZE_TYPE__, __PTRDIFF_TYPE__ and __WCHAR_TYPE__ are the predefines of
+ * GCC and undocumented in GCC 2.
+ */
+#if __GNUC__ == 2
+#define COMPILER_SP1 "__SIZE_TYPE__"
+#define COMPILER_SP2 "__PTRDIFF_TYPE__"
+#define COMPILER_SP3 "__WCHAR_TYPE__"
+#endif
+
+#define CMP_NAME "GCC"
+#endif /* COMPILER == GNUC */
+
+#if COMPILER == INDEPENDENT
+/* specifications of compiler-independent-build */
+#define LINE_PREFIX "#line "
+#define STD_LINE_PREFIX TRUE /* Output #line by C source format */
+#define HAVE_DIGRAPHS TRUE /* Output digraphs as it is */
+#define SEARCH_INIT SOURCE /* Include directory relative to source */
+#define SJIS_IS_ESCAPE_FREE TRUE /* Do not treat SJIS specially */
+#define BIGFIVE_IS_ESCAPE_FREE TRUE /* Do not treat specially */
+#define ISO2022_JP_IS_ESCAPE_FREE TRUE /* Do not treat specially */
+#define TARGET_HAVE_LONG_LONG TRUE /* dummy */
+#define STDC_VERSION 199409L /* Initial value of __STDC_VERSION__ */
+#endif
+
+/*
+ * defaults
+ */
+
+#ifdef SYSTEM_EXT
+#ifndef SYSTEM_EXT_VAL
+#define SYSTEM_EXT_VAL "1"
+#endif
+#endif
+#ifdef SYSTEM_EXT2
+#ifndef SYSTEM_EXT2_VAL
+#define SYSTEM_EXT2_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_STD1
+#ifndef COMPILER_STD1_VAL
+#define COMPILER_STD1_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_STD2
+#ifndef COMPILER_STD2_VAL
+#define COMPILER_STD2_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_EXT
+#ifndef COMPILER_EXT_VAL
+#define COMPILER_EXT_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_EXT2
+#ifndef COMPILER_EXT2_VAL
+#define COMPILER_EXT2_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_CPLUS
+#ifndef COMPILER_CPLUS_VAL
+#define COMPILER_CPLUS_VAL "1"
+#endif
+#endif
+
+#ifndef ENV_C_INCLUDE_DIR
+#define ENV_C_INCLUDE_DIR "INCLUDE"
+#endif
+#ifndef ENV_CPLUS_INCLUDE_DIR
+#define ENV_CPLUS_INCLUDE_DIR "CPLUS_INCLUDE"
+#endif
+
+#ifndef ENV_SEP
+#if SYS_FAMILY == SYS_WIN
+#define ENV_SEP ';'
+#else
+#define ENV_SEP ':'
+#endif
+#endif
+
+#ifndef ONE_PASS
+#define ONE_PASS FALSE
+#endif
+
+/*
+ * CHARBIT, UCHARMAX are respectively CHAR_BIT, UCHAR_MAX of target compiler.
+ * CHARBIT should be defined to the number of bits per character.
+ * It is needed only for processing of multi-byte character constants.
+ * UCHARMAX should be defined to the maximum value of type unsigned char
+ * or maximum value of unsigned int which is converted from type (signed)
+ * char.
+ *
+ * LONGMAX should be defined to the LONG_MAX in <limits.h>.
+ * ULONGMAX should be defined to the ULONG_MAX in <limits.h>.
+ */
+
+#include "limits.h"
+#define CHARBIT CHAR_BIT
+#define UCHARMAX UCHAR_MAX
+#define USHRTMAX USHRT_MAX
+#define LONGMAX LONG_MAX
+#define ULONGMAX ULONG_MAX
+
+/*
+ * Define MBCHAR (multi-byte character encoding) to SJIS, EUC_JP or other.
+ */
+#ifndef MBCHAR
+#define MBCHAR 0
+#endif
+
+/*
+ * SJIS_IS_ESCAPE_FREE means the compiler does not escape '0x5c' ('\\') in
+ * shift-JIS encoded multi-byte character. SJIS_IS_ESCAPE_FREE == FALSE
+ * enables cpp to insert * '\\' before '\\' of the 2nd byte of SJIS code in
+ * literal. This insertion is for the compiler-proper which can't recognize
+ * SJIS literal.
+ * BIGFIVE_IS_ESCAPE_FREE means similar case on BIGFIVE encoding.
+ * ISO2022_JP_IS_ESCAPE_FREE means similar case on ISO2022_JP encoding.
+ *
+ * GCC can handle these encodings if it has been configured so.
+ */
+#ifndef SJIS_IS_ESCAPE_FREE
+#define SJIS_IS_ESCAPE_FREE FALSE /* or TRUE following your compiler */
+#endif
+#ifndef BIGFIVE_IS_ESCAPE_FREE
+#define BIGFIVE_IS_ESCAPE_FREE FALSE /* or TRUE following your compiler */
+#endif
+#ifndef ISO2022_JP_IS_ESCAPE_FREE
+#define ISO2022_JP_IS_ESCAPE_FREE FALSE /* or TRUE following compiler */
+#endif
+
+/*
+ * P A R T 2 Configurations for host-compiler.
+ *
+ * WARNING: In case of HOST_COMPILER differs from COMPILER, you must
+ * edit here and there of this part.
+ */
+
+#define HOST_HAVE_STPCPY HAVE_STPCPY
+#define HOST_HAVE_GETOPT HAVE_GETOPT
+#define HOST_LIB_IS_GLIBC LIB_IS_GLIBC
+
+/*
+ * Declaration of standard library functions and macros.
+ */
+
+/* stdin, stdout, stderr, FILE, NULL, fgets(), fputs() and other functions. */
+#include "stdio.h"
+
+/* FILENAMEMAX should be defined to FILENAME_MAX of host system. */
+#ifdef FILENAME_MAX
+#define FILENAMEMAX FILENAME_MAX
+#else
+#define FILENAMEMAX BUFSIZ
+#endif
+
+/* islower(), isupper(), toupper(), isdigit(), isxdigit(), iscntrl() */
+#include "ctype.h"
+
+/* errno */
+#include "errno.h"
+
+#include "string.h"
+#include "stdlib.h"
+#include "time.h"
+#include "setjmp.h"
+
+/* Functions other than standard. */
+#if ! HOST_HAVE_GETOPT || HOST_LIB_IS_GLIBC || HOST_SYSTEM == SYS_MINGW
+#define NEED_GETOPT TRUE
+#else
+#define NEED_GETOPT FALSE
+#endif
+
+extern char * stpcpy( char * dest, const char * src);
+
+/* For debugging malloc systems by kmatsui */
+#if KMMALLOC && _MEM_DEBUG
+#include "xalloc.h"
+#endif
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/directive.cpp b/TAO/TAO_IDL/contrib/mcpp/directive.cpp
new file mode 100644
index 00000000000..7b290b8ccee
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/directive.cpp
@@ -0,0 +1,1520 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * D I R E C T I V E . C
+ * P r o c e s s D i r e c t i v e L i n e s
+ *
+ * The routines to handle directives other than #include and #pragma
+ * are placed here.
+ */
+
+#if PREPROCESSED
+#include "mcpp.H"
+#else
+#include "system.H"
+#include "internal.H"
+#endif
+
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_ctype.h"
+
+static int do_if( int hash);
+ /* #if, #elif, #ifdef, #ifndef */
+static long do_line( void);
+ /* Process #line directive */
+static int get_parm( void);
+ /* Get parm., its nargs, names, lens*/
+static int get_repl( const char * macroname);
+ /* Get replacement embedded parm-no.*/
+static char * is_formal( const char * name, int conv);
+ /* If formal param., save the num. */
+static char * def_stringization( char * repl_cur);
+ /* Define stringization */
+static char * mgtoken_save( const char * macroname);
+ /* Prefix DEF_MAGIC to macro name */
+static char * str_parm_scan( char * string_end);
+ /* Scan the param. in string */
+static void do_undef( void);
+ /* Process #undef directive */
+static void dump_repl( const DEFBUF * dp, FILE * fp);
+ /* Dump replacement text */
+
+/*
+ * Generate (by hand-inspection) a set of unique values for each directive.
+ * MCPP won't compile if there are hash conflicts.
+ */
+
+#define L_if ('i' ^ (EOS << 1))
+#define L_ifdef ('i' ^ ('e' << 1))
+#define L_ifndef ('i' ^ ('d' << 1))
+#define L_elif ('e' ^ ('f' << 1))
+#define L_else ('e' ^ ('e' << 1))
+#define L_endif ('e' ^ ('i' << 1))
+#define L_define ('d' ^ ('i' << 1))
+#define L_undef ('u' ^ ('e' << 1))
+#define L_line ('l' ^ ('e' << 1))
+#define L_include ('i' ^ ('l' << 1))
+#if COMPILER == GNUC
+#define L_include_next ('i' ^ ('l' << 1) ^ ('_' << 1))
+#endif
+#define L_error ('e' ^ ('o' << 1))
+#define L_pragma ('p' ^ ('g' << 1))
+
+static const char * const not_ident
+ = "Not an identifier \"%s\""; /* _E_ */
+static const char * const no_arg = "No argument"; /* _E_ */
+static const char * const excess
+ = "Excessive token sequence \"%s\""; /* _E_ _W1_ */
+
+void directive( void)
+/*
+ * Process #directive lines. Each directive have their own subroutines.
+ */
+{
+ const char * const many_nesting =
+"More than %.0s%ld nesting of #if (#ifdef) sections%s"; /* _F_ _W4_ _W8_ */
+ const char * const not_in_section
+ = "Not in a #if (#ifdef) section in a source file"; /* _E_ _W1_ */
+ const char * const illeg_dir
+ = "Illegal #directive \"%s%.0ld%s\""; /* _E_ _W1_ _W8_ */
+ const char * const in_skipped = " (in skipped block)"; /* _W8_ */
+ FILEINFO * file;
+ int token_type;
+ int hash;
+ int c;
+ char * tp;
+
+ in_directive = TRUE;
+ if (keep_comments) {
+ mcpp_fputc( '\n', OUT); /* Possibly flush out comments */
+ newlines--;
+ }
+ c = skip_ws();
+ if (c == '\n') /* 'null' directive */
+ goto ret;
+ token_type = scan_token( c, (workp = work_buf, &workp), work_end);
+ if (in_asm && (token_type != NAM /* In #asm block */
+ || (! str_eq( identifier, "asm") /* Ignore #anything */
+ && ! str_eq( identifier, "endasm")))) /* other */
+ goto skip_line; /* than #asm or #endasm */
+ if (token_type != NAM) {
+ if (mcpp_mode == OLD_PREP && token_type == NUM) { /* # 123 [fname]*/
+ ACE_OS::strcpy( identifier, "line");
+ } else {
+ if (compiling) {
+ if (lang_asm) {
+ if (warn_level & 1)
+ cwarn( illeg_dir, work_buf, 0L, 0);
+ } else {
+ cerror( illeg_dir, work_buf, 0L, 0);
+ }
+ } else if (warn_level & 8) {
+ cwarn( illeg_dir, work_buf, 0L, in_skipped);
+ }
+ goto skip_line;
+ }
+ }
+ if (identifier[ 2] == EOS)
+ identifier[ 3] = EOS; /* Diddle */
+ hash = (identifier[ 1] == EOS) ? identifier[ 0]
+ : (identifier[ 0] ^ (identifier[ 3] << 1));
+ if (ACE_OS::strlen( identifier) > 7)
+ hash ^= (identifier[ 7] << 1);
+
+ switch (hash) {
+ case L_if: tp = "if"; break;
+ case L_ifdef: tp = "ifdef"; break;
+ case L_ifndef: tp = "ifndef"; break;
+ case L_elif: tp = "elif"; break;
+ case L_else: tp = "else"; break;
+ case L_endif: tp = "endif"; break;
+ case L_define: tp = "define"; break;
+ case L_undef: tp = "undef"; break;
+ case L_line: tp = "line"; break;
+ case L_include: tp = "include"; break;
+#if COMPILER == GNUC
+ case L_include_next: tp = "include_next"; break;
+#endif
+ case L_error: tp = "error"; break;
+ case L_pragma: tp = "pragma"; break;
+ default: tp = 0; break;
+ }
+
+ if (tp != 0 && ! str_eq( identifier, tp)) { /* Hash conflict*/
+ hash = 0; /* Unknown directive, will */
+ tp = 0; /* be handled by do_old() */
+ }
+
+ /*
+ * hash is set to a unique value corresponding to the directive.
+ */
+ if (! compiling) { /* Not compiling now */
+ switch (hash) {
+ case L_elif :
+ if (! standard) {
+ if (warn_level & 8)
+ do_old(); /* Unknown directive */
+ goto skip_line; /* Skip the line */
+ } /* Else fall through */
+ case L_else : /* Test the #if's nest, if 0, compile */
+ case L_endif: /* Un-nest #if */
+ break;
+ case L_if : /* These can't turn */
+ case L_ifdef: /* compilation on, but */
+ case L_ifndef: /* we must nest #if's.*/
+ if (&ifstack[ BLK_NEST] < ++ifptr)
+ goto if_nest_err;
+ if (standard && (warn_level & 8)
+ && &ifstack[ blk_nest_min + 1] == ifptr)
+ cwarn( many_nesting, 0, (long) blk_nest_min, in_skipped);
+ ifptr->stat = 0; /* !WAS_COMPILING */
+ ifptr->ifline = src_line; /* Line at section start*/
+ goto skip_line;
+ default : /* Other directives */
+ if (tp == 0 && (warn_level & 8))
+ do_old(); /* Unknown directive ? */
+ goto skip_line; /* Skip the line */
+ }
+ }
+ macro_line = 0; /* Reset error flag */
+ file = infile; /* Remember the current file */
+
+ switch (hash) {
+
+ case L_if:
+ case L_ifdef:
+ case L_ifndef:
+ if (&ifstack[ BLK_NEST] < ++ifptr)
+ goto if_nest_err;
+ if (standard && (warn_level & 4) &&
+ &ifstack[ blk_nest_min + 1] == ifptr)
+ cwarn( many_nesting, 0 , (long) blk_nest_min, 0);
+ ifptr->stat = WAS_COMPILING;
+ ifptr->ifline = src_line;
+ goto ifdo;
+
+ case L_elif:
+ if (! standard) {
+ do_old(); /* Unrecognized directive */
+ break;
+ }
+ if (ifptr == &ifstack[0])
+ goto nest_err;
+ if (ifptr == infile->initif) {
+ goto in_file_nest_err;
+ }
+ if (ifptr->stat & ELSE_SEEN)
+ goto else_seen_err;
+ if ((ifptr->stat & (WAS_COMPILING | TRUE_SEEN)) != WAS_COMPILING) {
+ compiling = FALSE; /* Done compiling stuff */
+ goto skip_line; /* Skip this group */
+ }
+ hash = L_if;
+ifdo:
+ c = do_if( hash);
+ if (mcpp_debug & IF) {
+ mcpp_fprintf( DBG
+ , "#if (#elif, #ifdef, #ifndef) evaluate to %s.\n"
+ , compiling ? "TRUE" : "FALSE");
+ mcpp_fprintf( DBG, "line %ld: %s", src_line, infile->buffer);
+ }
+ if (c == FALSE) { /* Error */
+ compiling = FALSE; /* Skip this group */
+ goto skip_line; /* Prevent an extra error message */
+ }
+ break;
+
+ case L_else:
+ if (ifptr == &ifstack[0])
+ goto nest_err;
+ if (ifptr == infile->initif) {
+ if (standard)
+ goto in_file_nest_err;
+ else if (warn_level & 1)
+ cwarn( not_in_section, 0, 0L, 0);
+ }
+ if (ifptr->stat & ELSE_SEEN)
+ goto else_seen_err;
+ ifptr->stat |= ELSE_SEEN;
+ ifptr->elseline = src_line;
+ if (ifptr->stat & WAS_COMPILING) {
+ if (compiling || (ifptr->stat & TRUE_SEEN) != 0)
+ compiling = FALSE;
+ else
+ compiling = TRUE;
+ }
+ break;
+
+ case L_endif:
+ if (ifptr == &ifstack[0])
+ goto nest_err;
+ if (ifptr <= infile->initif) {
+ if (standard)
+ goto in_file_nest_err;
+ else if (warn_level & 1)
+ cwarn( not_in_section, 0, 0L, 0);
+ }
+ if (! compiling && (ifptr->stat & WAS_COMPILING))
+ wrong_line = TRUE;
+ compiling = (ifptr->stat & WAS_COMPILING);
+ --ifptr;
+ break;
+
+ case L_define:
+ do_define( FALSE);
+ break;
+
+ case L_undef:
+ do_undef();
+ break;
+
+ case L_line:
+ if ((c = do_line()) > 0) {
+ src_line = c;
+ sharp(); /* Putout the new line number and file name */
+ infile->line = --src_line; /* Next line number is 'src_line' */
+ newlines = -1;
+ } else { /* Error already diagnosed by do_line() */
+ skip_nl();
+ }
+ break;
+
+ case L_include:
+ in_include = TRUE;
+ if (do_include( FALSE) == TRUE && file != infile)
+ newlines = -1; /* File has been included. Clear blank lines */
+ in_include = FALSE;
+ break;
+
+ case L_error:
+ if (! standard) {
+ do_old(); /* Unrecognized directive */
+ break;
+ }
+ cerror( infile->buffer, 0, 0L, 0); /* _E_ */
+ break;
+
+ case L_pragma:
+ if (! standard) {
+ do_old(); /* Unrecognized directive */
+ break;
+ }
+ do_pragma();
+ newlines = -1; /* Do not putout excessive '\n' */
+ break;
+
+ default: /* Non-Standard or unknown directives */
+ do_old();
+ break;
+ }
+
+ switch (hash) {
+ case L_if :
+ case L_define :
+ case L_line :
+ goto skip_line; /* To prevent duplicate error message */
+#if COMPILER == GNUC
+ case L_include_next :
+ if (file != infile) /* File has been included */
+ newlines = -1;
+#endif
+ case L_error :
+ if (standard)
+ goto skip_line;
+ /* Else fall through */
+ case L_include :
+ case L_pragma :
+ if (standard)
+ break; /* Already read over the line */
+ /* Else fall through */
+ default : /* L_else, L_endif, L_undef, etc. */
+ if (mcpp_mode == OLD_PREP) {
+ /*
+ * Ignore the rest of the #directive line so you can write
+ * #if foo
+ * #endif foo
+ */
+ ;
+ } else if (skip_ws() != '\n') {
+ if (standard)
+ cerror( excess, infile->bptr-1, 0L, 0);
+ else if (warn_level & 1)
+ cwarn( excess, infile->bptr-1, 0L, 0);
+ }
+ skip_nl();
+ }
+ goto ret;
+
+in_file_nest_err:
+ cerror( not_in_section, 0, 0L, 0);
+ goto skip_line;
+nest_err:
+ cerror( "Not in a #if (#ifdef) section", 0, 0L, 0); /* _E_ */
+ goto skip_line;
+else_seen_err:
+ cerror( "Already seen #else at line %.0s%ld" /* _E_ */
+ , 0, ifptr->elseline, 0);
+skip_line:
+ skip_nl(); /* Ignore rest of line */
+ goto ret;
+
+if_nest_err:
+ cfatal( many_nesting, 0, (long) BLK_NEST, 0);
+
+ret:
+ in_directive = FALSE;
+ keep_comments = cflag && compiling && !no_output;
+ if (! wrong_line)
+ newlines++;
+}
+
+static int do_if( int hash)
+/*
+ * Process an #if (#elif), #ifdef or #ifndef. The latter two are straight-
+ * forward, while #if needs a subroutine of its own to evaluate the
+ * expression.
+ * do_if() is called only if compiling is TRUE. If false, compilation is
+ * always supressed, so we don't need to evaluate anything. This supresses
+ * unnecessary warnings.
+ */
+{
+ int c;
+ int found;
+
+ if ((c = skip_ws()) == '\n') {
+ unget_ch();
+ cerror( no_arg, 0, 0L, 0);
+ return FALSE;
+ }
+ if (hash == L_if) { /* #if or #elif */
+ unget_ch();
+ found = (eval_if() != 0L); /* Evaluate expression */
+ hash = L_ifdef; /* #if is now like #ifdef */
+ } else { /* #ifdef or #ifndef */
+ if (scan_token( c, (workp = work_buf, &workp), work_end) != NAM) {
+ cerror( not_ident, work_buf, 0L, 0);
+ return FALSE; /* Next token is not an identifier */
+ }
+ found = (look_id( identifier) != 0); /* Look in table */
+ }
+ if (found == (hash == L_ifdef)) {
+ compiling = TRUE;
+ ifptr->stat |= TRUE_SEEN;
+ } else {
+ compiling = FALSE;
+ }
+ return TRUE;
+}
+
+static long do_line( void)
+/*
+ * Parse the line to update the line number and "filename" field for the next
+ * input line.
+ * Values returned are as follows:
+ * -1: syntax error or out-of-range error (diagnosed by do_line(),
+ * eval_num()).
+ * [1,32767]: legal line number for C90, [1,2147483647] for C99.
+ * Line number [32768,2147483647] in C90 mode is only warned (not an error).
+ * do_line() always absorbs the line (except the <newline>).
+ */
+{
+ const char * const not_digits
+ = "Line number \"%s\" isn't a decimal digits sequence"; /* _E_ _W1_ */
+ const char * const out_of_range
+ = "Line number \"%s\" is out of range of [1,%ld]"; /* _E_ _W1_ */
+ int token_type;
+ VAL_SIGN * valp;
+ char * save;
+ int c;
+
+ if ((c = skip_ws()) == '\n') {
+ cerror( no_arg, 0, 0L, 0);
+ unget_ch(); /* Push back <newline> */
+ return -1L; /* Line number is not changed */
+ }
+
+ if (standard) {
+ token_type = get_unexpandable( c, FALSE);
+ if (macro_line == MACRO_ERROR) /* Unterminated macro */
+ return -1L; /* already diagnosed. */
+ if (token_type == NO_TOKEN) /* Macro expanded to 0 token */
+ goto no_num;
+ if (token_type != NUM)
+ goto illeg_num;
+ } else if (scan_token( c, (workp = work_buf, &workp), work_end) != NUM) {
+ goto illeg_num;
+ }
+ for (workp = work_buf; *workp != EOS; workp++) {
+ if (! ACE_OS::ace_isdigit( *workp & UCHARMAX)) {
+ if (standard) {
+ cerror( not_digits, work_buf, 0L, 0);
+ return -1L;
+ } else if (warn_level & 1) {
+ cwarn( not_digits, work_buf, 0L, 0);
+ }
+ }
+ }
+ valp = eval_num( work_buf); /* Evaluate number */
+ if (valp->sign == VAL_ERROR) { /* Error diagnosed by eval_num()*/
+ return -1;
+ } else if (standard && (line_limit < valp->val || valp->val <= 0L)) {
+ if (valp->val < LINE99LIMIT && valp->val > 0L) {
+ if (warn_level & 1)
+ cwarn( out_of_range, work_buf, line_limit, 0);
+ } else {
+ cerror( out_of_range, work_buf, line_limit, 0);
+ return -1L;
+ }
+ }
+
+ if (standard) {
+ token_type = get_unexpandable( skip_ws(), FALSE);
+ if (macro_line == MACRO_ERROR)
+ return -1L;
+ if (token_type != STR) {
+ if (token_type == NO_TOKEN) { /* Filename is absent */
+ return (long) valp->val;
+ } else { /* Expanded macro should be a quoted string */
+ goto not_fname;
+ }
+ }
+ } else {
+ if ((c = skip_ws()) == '\n') {
+ unget_ch();
+ return (long) valp->val;
+ }
+ if (scan_token( c, (workp = work_buf, &workp), work_end) != STR)
+ goto not_fname;
+ }
+#if COMPILER == GNUC
+ if (ACE_OS::memcmp( workp - 3, "//", 2) == 0) { /* "/cur-dir//" */
+ save = infile->filename; /* Do not change the file name */
+ } else
+#endif
+ {
+ *(workp - 1) = EOS; /* Ignore right '"' */
+ save = save_string( &work_buf[ 1]); /* Ignore left '"' */
+ }
+
+ if (standard) {
+ if (get_unexpandable( skip_ws(), FALSE) != NO_TOKEN) {
+ cerror( excess, work_buf, 0L, 0);
+ ACE_OS::free( save);
+ return -1L;
+ }
+ } else if (mcpp_mode == OLD_PREP) {
+ skip_nl();
+ unget_ch();
+ } else if ((c = skip_ws()) == '\n') {
+ unget_ch();
+ } else {
+ if (warn_level & 1) {
+ scan_token( c, (workp = work_buf, &workp), work_end);
+ cwarn( excess, work_buf, 0, 0);
+ }
+ skip_nl();
+ unget_ch();
+ }
+
+ if (infile->filename)
+ ACE_OS::free( infile->filename);
+ infile->filename = save; /* New file name */
+ /* Note that this does not change infile->real_fname */
+ return (long) valp->val; /* New line number */
+
+no_num:
+ cerror( "No line number", 0, 0L, 0); /* _E_ */
+ return -1L;
+illeg_num:
+ cerror( "Not a line number \"%s\"", work_buf, 0L, 0); /* _E_ */
+ return -1L;
+not_fname:
+ cerror( "Not a file name \"%s\"", work_buf, 0L, 0); /* _E_ */
+ return -1L;
+}
+
+/*
+ * M a c r o D e f i n i t i o n s
+ *
+ * Edit History (cpp4.c) of original version
+ * 31-Aug-84 MM USENET net.sources release
+ * 2-May-85 MM Latest revision
+ */
+
+/*
+ * look_id() Looks for the name in the defined symbol table. Returns a
+ * pointer to the definition if found, or 0 if not present.
+ * install_macro() Installs the definition. Updates the symbol table.
+ * undefine() Deletes the definition from the symbol table.
+ */
+
+/*
+ * Global work_buf[] are used to store #define parameter lists and parlist[]
+ * point to them.
+ * 'nargs' contains the actual number of parameters stored.
+ */
+static char * parlist[ NMACPARS]; /* -> Start of each parameter */
+static size_t parlen[ NMACPARS]; /* Length of parameter name */
+static int nargs; /* Number of parameters */
+static char * token_p; /* Pointer to the token scanned */
+static char * repl_base; /* Base of buffer for repl-text */
+static char * repl_end; /* End of buffer for repl-text */
+static const char * const no_ident = "No identifier"; /* _E_ */
+
+DEFBUF * do_define(
+ int ignore_redef /* Do not redefine */
+)
+/*
+ * Called from directive() when a #define is scanned or called from
+ * do_options() when a -D option is scanned. This module parses formal
+ * parameters by get_parm() and the replacement text by get_repl().
+ *
+ * There is some special case code to distinguish
+ * #define foo bar -- object-like macro
+ * from #define foo() bar -- function-like macro with no parameter
+ *
+ * Also, we make sure that
+ * #define foo foo
+ * expands to "foo" but doesn't put MCPP into an infinite loop.
+ *
+ * A warning is printed if you redefine a symbol with a non-identical
+ * text. I.e,
+ * #define foo 123
+ * #define foo 123
+ * is ok, but
+ * #define foo 123
+ * #define foo +123
+ * is not.
+ *
+ * The following subroutines are called from do_define():
+ * get_parm() parsing and remembering parameter names.
+ * get_repl() parsing and remembering replacement text.
+ *
+ * The following subroutines are called from get_repl():
+ * is_formal() is called when an identifier is scanned. It checks through
+ * the array of formal parameters. If a match is found, the
+ * identifier is replaced by a control byte which will be used
+ * to locate the parameter when the macro is expanded.
+ * def_stringization() is called when '#' operator is scanned. It surrounds
+ * the token to stringize with magic-codes.
+ *
+ * modes other than STD ignore difference of parameter names in macro
+ * redefinition.
+ */
+{
+ const char * const predef = "\"%s\" shouldn't be redefined"; /* _E_ */
+ char repl_list[ NMACWORK + IDMAX]; /* Replacement text */
+ char macroname[ IDMAX + 1]; /* Name of the macro defining */
+ DEFBUF * defp; /* -> Old definition */
+ DEFBUF ** prevp; /* -> Pointer to previous def in list */
+ int c;
+ int redefined; /* TRUE if redefined */
+ int dnargs = 0; /* defp->nargs */
+ int cmp; /* Result of name comparison */
+
+ repl_base = repl_list;
+ repl_end = & repl_list[ NMACWORK];
+ if ((c = skip_ws()) == '\n') {
+ cerror( no_ident, 0, 0L, 0);
+ unget_ch();
+ return 0;
+ } else if (scan_token( c, (workp = work_buf, &workp), work_end) != NAM) {
+ cerror( not_ident, work_buf, 0L, 0);
+ return 0;
+ } else {
+ prevp = look_prev( identifier, &cmp);
+ defp = *prevp;
+ if (standard) {
+ if (cmp || defp->push) { /* Not known or 'pushed' macro */
+ if (str_eq( identifier, "defined")
+ || ((stdc_val || cplus_val)
+ && str_eq( identifier, "__VA_ARGS__"))) {
+ cerror(
+ "\"%s\" shouldn't be defined", identifier, 0L, 0); /* _E_ */
+ return 0;
+ }
+ redefined = FALSE; /* Quite new definition */
+ } else { /* It's known: */
+ if (ignore_redef)
+ return defp;
+ dnargs = (defp->nargs == DEF_NOARGS-1) ? DEF_NOARGS
+ : defp->nargs;
+ if (dnargs < DEF_NOARGS - 1 /* Standard predefined */
+ || dnargs == DEF_PRAGMA /* _Pragma() pseudo-macro */
+ ) {
+ cerror( predef, identifier, 0L, 0);
+ return 0;
+ } else {
+ redefined = TRUE; /* Remember this fact */
+ }
+ }
+ } else {
+ if (cmp) {
+ redefined = FALSE; /* Quite new definition */
+ } else { /* It's known: */
+ if (ignore_redef)
+ return defp;
+ dnargs = (defp->nargs == DEF_NOARGS-1) ? DEF_NOARGS
+ : defp->nargs;
+ redefined = TRUE;
+ }
+ }
+ }
+ ACE_OS::strcpy( macroname, identifier); /* Remember the name */
+
+ in_define = TRUE; /* Recognize '#', '##' */
+ if (get_parm() == FALSE) { /* Get parameter list */
+ in_define = FALSE;
+ return 0; /* Syntax error */
+ }
+ if (get_repl( macroname) == FALSE) { /* Get replacement text */
+ in_define = FALSE;
+ return 0; /* Syntax error */
+ }
+
+ in_define = FALSE;
+ if (redefined) {
+ if (dnargs != nargs || ! str_eq( defp->repl, repl_list)
+ || (mcpp_mode == STD && ! str_eq( defp->parmnames, work_buf))
+ ) { /* Warn if differently redefined */
+ if (warn_level & 1) {
+ cwarn(
+ "The macro is redefined", 0, 0L, 0); /* _W1_ */
+ if (! no_source_line)
+ dump_a_def( " previously macro", defp, FALSE, FALSE
+ , TRUE, fp_err);
+ }
+ } else { /* Identical redefinition */
+ return defp;
+ }
+ } /* Else new or re-definition*/
+ defp = install_macro( macroname, nargs, work_buf, repl_list, prevp, cmp);
+ if (mcpp_mode == STD && cplus_val && id_operator( macroname)
+ && (warn_level & 1))
+ /* These are operators, not identifiers, in C++98 */
+ cwarn( "\"%s\" is defined as macro", macroname /* _W1_ */
+ , 0L, 0);
+ return defp;
+}
+
+static int get_parm( void)
+/*
+ * Get parameters i.e. numbers into nargs, name into work_buf[], name-length
+ * into parlen[].
+ * Return TRUE if the parameters are legal, else return FALSE.
+ * In STD mode preprocessor must remember the parameter names, only for
+ * checking the validity of macro redefinitions. This is required by the
+ * Standard (what an overhead !).
+ */
+{
+ const char * const many_parms
+ = "More than %.0s%ld parameters"; /* _E_ _W4_ */
+ const char * const illeg_parm
+ = "Illegal parameter \"%s\""; /* _E_ */
+ int token_type;
+ int c;
+
+ parlist[ 0] = workp = work_buf;
+ work_buf[ 0] = EOS;
+
+ /* POST_STD mode */
+ insert_sep = NO_SEP; /* Clear the inserted token separator */
+ c = get_ch();
+
+ if (c == '(') { /* With arguments? */
+ nargs = 0; /* Init parms counter */
+ if (skip_ws() == ')')
+ return TRUE; /* Macro with 0 parm */
+ else
+ unget_ch();
+
+ do { /* Collect parameters */
+ if (nargs >= NMACPARS) {
+ cerror( many_parms, 0, (long) NMACPARS, 0);
+ return FALSE;
+ }
+ parlist[ nargs] = workp; /* Save its start */
+ if ((token_type = scan_token( c = skip_ws(), &workp, work_end))
+ != NAM) {
+ if (c == '\n') {
+ break;
+ } else if (c == ',' || c == ')') {
+ cerror( "Empty parameter", 0, 0L, 0); /* _E_ */
+ return FALSE;
+ } else if (standard && (stdc_val || cplus_val)
+ && token_type == OPE && openum == OP_ELL) {
+ /*
+ * Enable variable argument macro which is a feature of
+ * C99. We enable this even on C90 or C++ for GCC
+ * compatibility.
+ */
+ if (skip_ws() != ')') {
+ cerror( "\"...\" isn't the last parameter", /* _E_ */
+ 0, 0L, 0);
+ return FALSE;
+ }
+ parlen[ nargs++] = 3;
+ nargs |= VA_ARGS;
+ goto ret;
+ } else {
+ cerror( illeg_parm , parlist[ nargs], 0L, 0);
+ return FALSE; /* Bad parameter syntax */
+ }
+ }
+ if (standard && (stdc_val || cplus_val)
+ && str_eq( identifier, "__VA_ARGS__")) {
+ cerror( illeg_parm, parlist[ nargs], 0L, 0);
+ return FALSE;
+ /* __VA_ARGS__ should not be used as a parameter */
+ }
+ if (is_formal( parlist[ nargs], FALSE)) {
+ cerror( "Duplicate parameter name \"%s\"" /* _E_ */
+ , parlist[ nargs], 0L, 0);
+ return FALSE;
+ }
+ parlen[ nargs] = (size_t) (workp - parlist[ nargs]);
+ /* Save length of param */
+ *workp++ = ',';
+ nargs++;
+ } while ((c = skip_ws()) == ','); /* Get another parameter*/
+
+ *--workp = EOS; /* Remove excessive ',' */
+ if (c != ')') { /* Must end at ) */
+ unget_ch(); /* Push back '\n' */
+ cerror(
+ "Missing \",\" or \")\" in parameter list \"(%s\"" /* _E_ */
+ , work_buf, 0L, 0);
+ return FALSE;
+ }
+ } else {
+ /*
+ * DEF_NOARGS is needed to distinguish between
+ * "#define foo" and "#define foo()".
+ */
+ nargs = DEF_NOARGS; /* Object-like macro */
+ unget_ch();
+ }
+ret:
+#if NMACPARS > NMACPARS90MIN
+ if ((warn_level & 4) && (nargs & ~AVA_ARGS) > n_mac_pars_min)
+ cwarn( many_parms, 0 , (long) n_mac_pars_min , 0);
+#endif
+ return TRUE;
+}
+
+static int get_repl( const char * macroname)
+/*
+ * Get replacement text i.e. names of formal parameters are converted to
+ * the magic numbers, and operators #, ## is converted to magic characters.
+ * Return TRUE if replacement list is legal, else return FALSE.
+ * Any token separator in the text is converted to a single space, no token
+ * sepatator is inserted by MCPP. Those are required by the Standard for
+ * stringizing of an argument by # operator.
+ * In POST_STD mode, inserts a space between any tokens in source (except a
+ * macro name and the next '(' in macro definition), hence presence or absence
+ * of token separator makes no difference.
+ */
+{
+ const char * const mixed_ops
+ = "Macro with mixing of ## and # operators isn't portable"; /* _W4_ */
+ const char * const multiple_cats
+ = "Macro with multiple ## operators isn't portable"; /* _W4_ */
+ char * prev_token = 0; /* Preceding token */
+ char * prev_prev_token = 0; /* Pre-preceding token */
+ int multi_cats = FALSE; /* Multiple ## operators*/
+ int c;
+ int token_type; /* Type of token */
+ char * temp;
+ char * repl_cur = repl_base; /* Pointer into repl-text buffer*/
+
+ *repl_cur = EOS;
+ token_p = 0;
+ if (mcpp_mode == STD) {
+ c = get_ch();
+ unget_ch();
+ if (((char_type[ c] & SPA) == 0) && (nargs < 0) && (warn_level & 1))
+ cwarn( "No space between macro name \"%s\" and repl-text"/* _W1_ */
+ , macroname, 0L, 0);
+ }
+ c = skip_ws(); /* Get to the body */
+
+ while (c != CHAR_EOF && c != '\n') {
+ if (standard) {
+ prev_prev_token = prev_token;
+ prev_token = token_p;
+ }
+ token_p = repl_cur; /* Remember the pointer */
+ token_type = scan_token( c, &repl_cur, repl_end);
+
+ switch (token_type) {
+ case OPE: /* Operator or punctuator */
+ if (! standard)
+ break;
+ switch (openum) {
+ case OP_CAT: /* ## */
+ if (prev_token == 0) {
+ cerror( "No token before ##" /* _E_ */
+ , 0, 0L, 0);
+ return FALSE;
+ } else if (*prev_token == CAT) {
+ cerror( "## after ##", 0, 0L, 0); /* _E_ */
+ return FALSE;
+ } else if (prev_prev_token && *prev_prev_token == CAT) {
+ multi_cats = TRUE;
+ } else if (prev_prev_token && *prev_prev_token == ST_QUOTE
+ && (warn_level & 4)) { /* # parm ## */
+ cwarn( mixed_ops, 0, 0L, 0);
+ }
+ repl_cur = token_p;
+ *repl_cur++ = CAT; /* Convert to CAT */
+ break;
+ case OP_STR: /* # */
+ if (nargs < 0) /* In object-like macro */
+ break; /* '#' is an usual char */
+ if (prev_token && *prev_token == CAT
+ && (warn_level & 4)) /* ## # */
+ cwarn( mixed_ops, 0, 0L, 0);
+ repl_cur = token_p; /* Overwrite on # */
+ if ((temp = def_stringization( repl_cur)) == 0) {
+ return FALSE; /* Error */
+ } else {
+ repl_cur = temp;
+ }
+ break;
+ default: /* Any operator as it is */
+ break;
+ }
+ break;
+ case NAM:
+ /*
+ * Replace this name if it's a parm. Note that the macro name is a
+ * possible replacement token. We stuff DEF_MAGIC in front of the
+ * token which is treated as a LETTER by the token scanner and eaten
+ * by the macro expanding routine. This prevents the macro expander
+ * from looping if someone writes "#define foo foo".
+ */
+ temp = is_formal( identifier, TRUE);
+ if (temp == 0) { /* Not a parameter name */
+ if (! standard)
+ break;
+ if ((stdc_val || cplus_val)
+ && str_eq( identifier, "__VA_ARGS__")) {
+ cerror( "\"%s\" without corresponding \"...\"" /* _E_ */
+ , identifier, 0L, 0);
+ return FALSE;
+ }
+ if ((temp = mgtoken_save( macroname)) != 0)
+ repl_cur = temp; /* Macro name */
+ } else { /* Parameter name */
+ repl_cur = temp;
+#if COMPILER == GNUC
+ if (mcpp_mode == STD && str_eq( identifier, "__VA_ARGS__")
+ && prev_token && *prev_token == CAT
+ && prev_prev_token && *prev_prev_token == ',')
+ /* ", ## __VA_ARGS__" sequence */
+ /* This is a GCC3-specific variadic macro */
+ nargs |= GVA_ARGS; /* Mark as GCC3 variadic*/
+#endif
+ }
+ break;
+
+ case STR: /* String in mac. body */
+ case CHR: /* Character constant */
+ if (mcpp_mode == OLD_PREP)
+ repl_cur = str_parm_scan( repl_cur);
+ break;
+ case SEP:
+ if (mcpp_mode == OLD_PREP && c == COM_SEP)
+ repl_cur--; /* Skip comment now */
+ break;
+ default: /* Any token as it is */
+ break;
+ }
+
+ c = get_ch();
+ if (c == ' ') {
+ *repl_cur++ = ' ';
+ c = get_ch();
+ }
+ }
+
+ unget_ch(); /* For syntax check */
+ if (standard) {
+ if (token_p && *token_p == CAT) {
+ cerror( "No token after ##", 0, 0L, 0); /* _E_ */
+ return FALSE;
+ }
+ if (multi_cats && (warn_level & 4))
+ cwarn( multiple_cats, 0, 0L, 0);
+ if ((nargs & VA_ARGS) && stdc_ver < 199901L && (warn_level & 2))
+ /* Variable arg macro is the spec of C99, not C90 nor C++98 */
+ cwarn( "Variable argument macro is defined", /* _W2_ */
+ 0, 0L, 0);
+ }
+ *repl_cur = EOS; /* Terminate work */
+
+ return TRUE;
+}
+
+static char * is_formal(
+ const char * name,
+ int conv /* Convert to magic number? */
+)
+/*
+ * If the identifier is a formal parameter, save the MAC_PARM and formal
+ * offset, returning the advanced pointer into the replacement text.
+ * Else, return 0.
+ */
+{
+ char * repl_cur;
+ size_t len;
+ int i;
+
+ len = ACE_OS::strlen( name);
+ for (i = 0; i < (nargs & ~AVA_ARGS); i++) { /* For each parameter */
+ if ((len == parlen[ i] /* Note: parlist[] are comma separated */
+ && ACE_OS::memcmp( name, parlist[ i], parlen[ i]) == 0)
+ || (standard && (nargs & VA_ARGS)
+ && i == (nargs & ~AVA_ARGS) - 1 && conv
+ && ACE_OS::memcmp( name, "__VA_ARGS__", 12) == 0)) {
+ /* If it's known */
+ if (conv) {
+ repl_cur = token_p; /* Overwrite on the name*/
+ *repl_cur++ = MAC_PARM; /* Save the signal */
+ *repl_cur++ = i + 1; /* Save the parm number */
+ return repl_cur; /* Return "gotcha" */
+ } else {
+ return parlist[ i]; /* Duplicate parm name */
+ }
+ }
+ }
+
+ return 0; /* Not a formal param */
+}
+
+static char * def_stringization( char * repl_cur)
+/*
+ * Define token stringization.
+ * We store a magic cookie (which becomes " on output) preceding the
+ * parameter as an operand of # operator.
+ * Return the current pointer into replacement text if the token following #
+ * is a parameter name, else return 0.
+ */
+{
+ int c;
+ char * temp;
+
+ *repl_cur++ = ST_QUOTE; /* prefix */
+ if ((c = get_ch()) == ' ') {
+ *repl_cur++ = ' ';
+ c = get_ch();
+ }
+ token_p = repl_cur; /* Remember the pointer */
+ if (scan_token( c, &repl_cur, repl_end) == NAM) {
+ if ((temp = is_formal( identifier, TRUE)) != 0) {
+ repl_cur = temp;
+ return repl_cur;
+ }
+ }
+ cerror( "Not a formal parameter \"%s\"", token_p, 0L, 0); /* _E_ */
+ return 0;
+}
+
+static char * mgtoken_save( const char * macroname)
+/*
+ * A magic cookie is inserted if the token is identical to the macro name,
+ * so the expansion doesn't recurse.
+ * Return the advanced pointer into the replacement text or 0.
+ */
+{
+ char * repl_cur;
+
+ if (str_eq( macroname, identifier)) { /* Macro name in body */
+ repl_cur = token_p; /* Overwrite on token */
+ *repl_cur++ = DEF_MAGIC; /* Save magic marker */
+ repl_cur = stpcpy( repl_cur, identifier);
+ /* And save the token */
+ return repl_cur;
+ } else {
+ return 0;
+ }
+}
+
+static char * str_parm_scan( char * string_end)
+/* FUZZ: disable check_for_lack_ACE_OS
+ * String parameter scan.
+ * This code -- if enabled -- recognizes a formal parameter in a string
+ * literal or in a character constant.
+ * #define foo(bar, v) printf("%bar\n", v)
+ * foo( d, i)
+ * expands to:
+ * printf("%d\n", i)
+ * str_parm_scan() return the advanced pointer into the replacement text.
+ * This has been superceded by # stringizing and string concatenation.
+ * This routine is called only in OLD_PREP mode.
+ */ //FUZZ: enable check_for_lack_ACE_OS
+{
+ int delim;
+ int c;
+ char * tp;
+ char * wp; /* Pointer into the quoted literal */
+
+ delim = *token_p;
+ unget_string( ++token_p, 0);
+ /* Pseudo-token-parsing in a string literal */
+ wp = token_p;
+ while ((c = get_ch()) != delim) {
+ token_p = wp;
+ if (scan_token( c, &wp, string_end) != NAM)
+ continue;
+ if ((tp = is_formal( token_p, TRUE)) != 0)
+ wp = tp;
+ }
+ *wp++ = delim;
+ return wp;
+}
+
+static void do_undef( void)
+/*
+ * Remove the symbol from the defined list.
+ * Called from directive().
+ */
+{
+ DEFBUF * defp;
+ int c;
+
+ if ((c = skip_ws()) == '\n') {
+ cerror( no_ident, 0, 0L, 0);
+ unget_ch();
+ return;
+ }
+ if (scan_token( c, (workp = work_buf, &workp), work_end) != NAM) {
+ cerror( not_ident, work_buf, 0L, 0);
+ skip_nl();
+ unget_ch();
+ } else {
+ if ((defp = look_id( identifier)) == 0) {
+ if (warn_level & 8)
+ cwarn( "\"%s\" wasn't defined" /* _W8_ */
+ , identifier, 0L, 0);
+ } else if (standard
+ && (defp->nargs < DEF_NOARGS - 1 /* Standard predef */
+ || defp->nargs == DEF_PRAGMA)) {
+ /* _Pragma() pseudo-macro */
+ cerror( "\"%s\" shouldn't be undefined" /* _E_ */
+ , identifier, 0L, 0);
+ } else if (standard) {
+ c = skip_ws();
+ unget_ch();
+ if (c != '\n') /* Trailing junk */
+ return;
+ else
+ undefine( identifier);
+ } else {
+ undefine( identifier);
+ }
+ }
+}
+
+/*
+ * C P P S y m b o l T a b l e s
+ *
+ * SBSIZE defines the number of hash-table slots for the symbol table.
+ * It must be a power of 2.
+ */
+
+/* Symbol table queue headers. */
+static DEFBUF * symtab[ SBSIZE];
+static long num_of_macro = 0;
+
+#if MCPP_LIB
+void init_directive( void)
+/* Initialize static variables. */
+{
+ num_of_macro = 0;
+}
+#endif
+
+DEFBUF * look_id( const char * name)
+/*
+ * Look for the identifier in the symbol table.
+ * If found, return the table pointer; Else return 0.
+ */
+{
+ DEFBUF ** prevp;
+ int cmp;
+
+ prevp = look_prev( name, &cmp);
+
+ if (standard)
+ return ((cmp == 0 && (*prevp)->push == 0) ? *prevp : 0);
+ else
+ return ((cmp == 0) ? *prevp : 0);
+}
+
+DEFBUF ** look_prev(
+ const char * name, /* Name of the macro */
+ int * cmp /* Result of comparison */
+)
+/*
+ * Look for the place to insert the macro definition.
+ * Return a pointer to the previous member in the linked list.
+ */
+{
+ const char * np;
+ DEFBUF ** prevp;
+ DEFBUF * dp;
+ size_t s_name;
+ int hash;
+
+ for (hash = 0, np = name; *np != EOS; )
+ hash += *np++;
+ hash += s_name = (size_t)(np - name);
+ s_name++;
+ prevp = & symtab[ hash & SBMASK];
+ *cmp = -1; /* Initialize */
+
+ while ((dp = *prevp) != 0) {
+ if ((*cmp = ACE_OS::memcmp( dp->name, name, s_name)) >= 0)
+ break;
+ prevp = &dp->link;
+ }
+
+ return prevp;
+}
+
+DEFBUF * look_and_install(
+ const char * name, /* Name of the macro */
+ int numargs, /* The numbers of parms */
+ const char * parmnames, /* Names of parameters concatenated */
+ const char * repl /* Replacement text */
+)
+/*
+ * Look for the name and (re)define it.
+ * Returns a pointer to the definition block.
+ * Returns 0 if the symbol was Standard-predefined.
+ */
+{
+ DEFBUF ** prevp; /* Place to insert definition */
+ DEFBUF * defp; /* New definition block */
+ int cmp; /* Result of comparison of new name and old */
+
+ prevp = look_prev( name, &cmp);
+ defp = install_macro( name, numargs, parmnames, repl, prevp, cmp);
+ return defp;
+}
+
+DEFBUF * install_macro(
+ const char * name, /* Name of the macro */
+ int numargs, /* The numbers of parms */
+ const char * parmnames, /* Names of parameters concatenated */
+ const char * repl, /* Replacement text */
+ DEFBUF ** prevp, /* The place to insert definition */
+ int cmp /* Result of comparison of new name and old */
+)
+/*
+ * Enter this name in the lookup table.
+ * Returns a pointer to the definition block.
+ * Returns 0 if the symbol was Standard-predefined.
+ */
+{
+ DEFBUF * dp;
+ DEFBUF * defp;
+ size_t s_name, s_parmnames, s_repl;
+
+ defp = *prevp;
+ if (cmp == 0 && defp->nargs < DEF_NOARGS - 1)
+ return 0; /* Standard predefined */
+ s_parmnames = 0;
+ if (parmnames == 0 || repl == 0) /* Shouldn't happen */
+ cfatal( "Bug: Illegal macro installation of \"%s\"" /* _F_ */
+ , name, 0L, 0); /* Use "" instead of 0 */
+ s_name = ACE_OS::strlen( name);
+ if (mcpp_mode == STD)
+ s_parmnames = ACE_OS::strlen( parmnames) + 1;
+ s_repl = ACE_OS::strlen( repl) + 1;
+ dp = (DEFBUF *)
+ xmalloc( sizeof (DEFBUF) + s_name + s_parmnames + s_repl);
+ if (cmp || (standard && (*prevp)->push)) { /* New definition */
+ dp->link = defp; /* Insert to linked list */
+ *prevp = dp;
+ } else { /* Redefinition */
+ dp->link = defp->link; /* Replace old def with new */
+ *prevp = dp;
+ ACE_OS::free( defp);
+ }
+ dp->nargs = numargs;
+ if (standard) {
+ dp->push = 0;
+ dp->parmnames = (char *)dp + sizeof (DEFBUF) + s_name;
+ dp->repl = dp->parmnames + s_parmnames;
+ if (mcpp_mode == STD)
+ ACE_OS::memcpy( dp->parmnames, parmnames, s_parmnames);
+ } else {
+ dp->repl = (char *)dp + sizeof (DEFBUF) + s_name;
+ }
+ ACE_OS::memcpy( dp->name, name, s_name + 1);
+ ACE_OS::memcpy( dp->repl, repl, s_repl);
+ /* Remember where the macro is defined */
+ dp->dir = *inc_dirp;
+ dp->fname = cur_fname;
+ dp->mline = src_line;
+ if (standard && cmp && ++num_of_macro == n_macro_min + 1 && n_macro_min
+ && (warn_level & 4))
+ cwarn( "More than %.0s%ld macros defined" /* _W4_ */
+ , 0 , n_macro_min , 0);
+ return dp;
+}
+
+int undefine(
+ const char * name /* Name of the macro */
+)
+/*
+ * Delete the macro definition from the symbol table.
+ * Returns TRUE, if deleted;
+ * Else returns FALSE (when the macro was not defined or was predefined).
+ */
+{
+ DEFBUF ** prevp; /* Preceding definition in list */
+ DEFBUF * dp; /* Definition to delete */
+ int cmp;
+
+ prevp = look_prev( name, &cmp);
+ dp = *prevp; /* Definition to delete */
+ if (cmp || dp->nargs < DEF_NOARGS - 1)
+ return FALSE; /* Standard predefined */
+ if (standard && dp->push)
+ return FALSE; /* 'Pushed' macro */
+ *prevp = dp->link; /* Link the previous and the next */
+ ACE_OS::free( dp); /* Delete the definition */
+ if (standard)
+ num_of_macro--;
+ return TRUE;
+}
+
+static void dump_repl(
+ const DEFBUF * dp,
+ FILE * fp
+)
+/*
+ * Dump replacement text.
+ */
+{
+ int numargs = dp->nargs;
+ char * cp1;
+ size_t i;
+ int c;
+ const char * cp;
+
+ for (cp = dp->repl; (c = *cp++ & UCHARMAX) != EOS; ) {
+
+ switch (c) {
+ case MAC_PARM: /* Parameter */
+ c = (*cp++ & UCHARMAX) - 1;
+ if (standard) {
+ if ((numargs & VA_ARGS) && c == (numargs & ~AVA_ARGS) - 1) {
+ mcpp_fputs( "__VA_ARGS__", FP2DEST( fp));
+ } else {
+ if (mcpp_mode == STD) {
+ for (i = 0, cp1 = parlist[ c]; i < parlen[ c]; i++)
+ mcpp_fputc( *cp1++, FP2DEST( fp));
+ } else {
+ mcpp_fputc( 'a' + c % 26, FP2DEST( fp));
+ if (c > 26)
+ mcpp_fputc( '0' + c / 26, FP2DEST( fp));
+ }
+ }
+ } else {
+ mcpp_fputc( 'a' + c % 26, FP2DEST( fp));
+ if (c > 26)
+ mcpp_fputc( '0' + c / 26, FP2DEST( fp));
+ }
+ break;
+ case DEF_MAGIC:
+ if (! standard)
+ mcpp_fputc( c, FP2DEST( fp));
+ /* Else skip */
+ break;
+ case CAT:
+ if (standard)
+ mcpp_fputs( "##", FP2DEST( fp));
+ else
+ mcpp_fputc( c, FP2DEST( fp));
+ break;
+ case ST_QUOTE:
+ if (standard)
+ mcpp_fputs( "#", FP2DEST( fp));
+ else
+ mcpp_fputc( c, FP2DEST( fp));
+ break;
+ case COM_SEP:
+ /*
+ * Though TOK_SEP coincides to COM_SEP, this cannot appear in
+ * Standard mode.
+ */
+ if (mcpp_mode == OLD_PREP)
+ mcpp_fputs( "/**/", FP2DEST( fp));
+ break;
+ default:
+ mcpp_fputc( c, FP2DEST( fp));
+ break;
+ }
+ }
+}
+
+/*
+ * If the compiler is so-called "one-pass" compiler, compiler-predefined
+ * macros are commented out to avoid redefinition.
+ */
+#if ONE_PASS
+#define CAN_REDEF DEF_NOARGS
+#else
+#define CAN_REDEF (DEF_NOARGS - 1)
+#endif
+
+void dump_a_def(
+ const char * why,
+ const DEFBUF * dp,
+ int newdef, /* TRUE if parmnames are currently in parlist[] */
+ int dDflag, /* TRUE if -dD option is used (for GCC) */
+ int comment, /* Show location of the definition in comment */
+ FILE * fp
+)
+/*
+ * Dump a macro definition.
+ */
+{
+ char * cp, * cp1;
+ int numargs = dp->nargs & ~AVA_ARGS;
+ int commented; /* To be commented out */
+ int i;
+
+ if (standard && numargs == DEF_PRAGMA) /* _Pragma pseudo-macro */
+ return;
+ if ((numargs < CAN_REDEF) || (dDflag && (numargs == DEF_NOARGS - 1))
+ || (standard && dp->push))
+ commented = TRUE;
+ else
+ commented = FALSE;
+ if (! comment && commented) /* For -dM option */
+ return;
+ if (why)
+ mcpp_fprintf( FP2DEST( fp), "%s \"%s\" defined as: ", why, dp->name);
+ mcpp_fprintf( FP2DEST( fp), "%s#define %s", commented ? "/* " : "",
+ dp->name); /* Macro name */
+ if (numargs >= 0) { /* Parameter list */
+ if (mcpp_mode == STD) {
+ mcpp_fprintf( FP2DEST( fp), "(%s)", dp->parmnames);
+ if (! newdef) {
+ for (i = 0, cp = dp->parmnames; i < numargs;
+ i++, cp = cp1 + 1) {
+ if ((cp1 = ACE_OS::strchr( cp, ',')) == 0) /* The last arg */
+ parlen[ i] = ACE_OS::strlen( cp);
+ else
+ parlen[ i] = (size_t) (cp1 - cp);
+ parlist[ i] = cp;
+ }
+ }
+ } else {
+ if (newdef) {
+ mcpp_fprintf( FP2DEST( fp), "(%s)", parlist[0]);
+ } else if (numargs == 0) {
+ mcpp_fputs( "()", FP2DEST( fp));
+ } else {
+ mcpp_fputc( '(', FP2DEST( fp));
+ for (i = 0; i < numargs; i++) { /* Make parameter list */
+ mcpp_fputc( 'a' + i % 26, FP2DEST( fp));
+ if (i >= 26)
+ mcpp_fputc( '0' + i / 26, FP2DEST( fp));
+ if (i + 1 < numargs)
+ mcpp_fputc( ',', FP2DEST( fp));
+ }
+ mcpp_fputc( ')', FP2DEST( fp));
+ }
+ }
+ }
+ if (*dp->repl) {
+ mcpp_fputc( ' ', FP2DEST( fp));
+ dump_repl( dp, fp); /* Replacement text */
+ }
+ if (commented)
+ /* Standard predefined or one-pass-compiler-predefined */
+ mcpp_fputs( " */", FP2DEST( fp));
+ if (comment) /* Not -dM option */
+ mcpp_fprintf( FP2DEST( fp), " \t/* %s%s:%ld\t*/", dp->dir, dp->fname
+ , dp->mline);
+ mcpp_fputc( '\n', FP2DEST( fp));
+}
+
+void dump_def(
+ int dDflag, /* -dD option (for GCC) */
+ int comment /* Location of definition in comment */
+)
+/*
+ * Dump all the current macro definitions to output stream.
+ */
+{
+ DEFBUF * dp;
+ DEFBUF ** symp;
+
+ sharp(); /* Report the current source file & line */
+ if (comment)
+ mcpp_fputs( "/* Currently defined macros. */\n", OUT);
+ for (symp = symtab; symp < &symtab[ SBSIZE]; symp++) {
+ if ((dp = *symp) != 0) {
+ do {
+ dump_a_def( 0, dp, FALSE, dDflag, comment, fp_out);
+ } while ((dp = dp->link) != 0);
+ }
+ }
+ wrong_line = TRUE; /* Line number is out of sync */
+}
+
+#if MCPP_LIB
+void clear_symtable( void)
+/*
+ * ACE_OS::Free all the macro definitions.
+ */
+{
+ DEFBUF * next;
+ DEFBUF * dp;
+ DEFBUF ** symp;
+
+ for (symp = symtab; symp < &symtab[ SBSIZE]; symp++) {
+ for (next = *symp; next != 0; ) {
+ dp = next;
+ next = dp->link;
+ ACE_OS::free( dp); /* free the symbol */
+ }
+ *symp = 0;
+ }
+}
+#endif
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/eval.cpp b/TAO/TAO_IDL/contrib/mcpp/eval.cpp
new file mode 100644
index 00000000000..f75932f446e
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/eval.cpp
@@ -0,0 +1,1669 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * E V A L . C
+ * E x p r e s s i o n E v a l u a t i o n
+ *
+ * The routines to evaluate #if expression are placed here.
+ * Some routines are used also to evaluate the value of numerical tokens.
+ */
+
+#if PREPROCESSED
+#include "mcpp.H"
+#else
+#include "system.H"
+#include "internal.H"
+#endif
+
+#include "ace/OS_NS_ctype.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_stdlib.h"
+
+typedef struct optab {
+ char op; /* Operator */
+ char prec; /* Its precedence */
+ char skip; /* Short-circuit: non-0 to skip */
+} OPTAB;
+
+static int eval_lex( void);
+ /* Get type and value of token */
+static int chk_ops( void);
+ /* Check identifier-like ops */
+static VAL_SIGN * eval_char( char * const token);
+ /* Evaluate character constant */
+static expr_t eval_one( char ** seq_pp, int wide, int mbits, int * ucn8);
+ /* Evaluate a character */
+static VAL_SIGN * eval_eval( VAL_SIGN * valp, int op);
+ /* Entry to #if arithmetic */
+static expr_t eval_signed( VAL_SIGN ** valpp, expr_t v1, expr_t v2, int op);
+ /* Do signed arithmetic of expr.*/
+static expr_t eval_unsigned( VAL_SIGN ** valpp, uexpr_t v1u, uexpr_t v2u
+ , int op);
+ /* Do unsigned arithmetic */
+static void overflow( const char * op_name, VAL_SIGN ** valpp
+ , int ll_overflow);
+ /* Diagnose overflow of expr. */
+static int do_sizeof( void);
+ /* Evaluate sizeof (type) */
+static int look_type( int typecode);
+ /* Look for type of the name */
+static void dump_val( const char * msg, const VAL_SIGN * valp);
+ /* Print value of an operand */
+static void dump_stack( const OPTAB * opstack, const OPTAB * opp
+ , const VAL_SIGN * value, const VAL_SIGN * valp);
+ /* Print stacked operators */
+
+/* For debug and error messages. */
+static const char * const opname[ OP_END + 1] = {
+ "end of expression", "val", "(",
+ "unary +", "unary -", "~", "!",
+ "*", "/", "%",
+ "+", "-", "<<", ">>",
+ "<", "<=", ">", ">=", "==", "!=",
+ "&", "^", "|", "&&", "||",
+ "?", ":",
+ ")", "(none)"
+};
+
+/*
+ * opdope[] has the operator (and operand) precedence:
+ * Bits
+ * 7 Unused (so the value is always positive)
+ * 6-2 Precedence (0000 .. 0174)
+ * 1-0 Binary op. flags:
+ * 10 The next binop flag (binop should/not follow).
+ * 01 The binop flag (should be set/cleared when this op is seen).
+ * Note: next binop
+ * value 1 0 Value doesn't follow value.
+ * Binop, ), END should follow value, value or unop doesn't.
+ * ( 0 0 ( doesn't follow value. Value follows.
+ * unary 0 0 Unop doesn't follow value. Value follows.
+ * binary 0 1 Binary op follows value. Value follows.
+ * ) 1 1 ) follows value. Binop, ), END follows.
+ * END 0 1 END follows value, doesn't follow ops.
+ */
+
+static const char opdope[ OP_END + 1] = {
+ 0001, /* End of expression */
+ 0002, 0170, /* VAL (constant), LPA */
+/* Unary op's */
+ 0160, 0160, 0160, 0160, /* PLU, NEG, COM, NOT */
+/* Binary op's */
+ 0151, 0151, 0151, /* MUL, DIV, MOD, */
+ 0141, 0141, 0131, 0131, /* ADD, SUB, SL, SR */
+ 0121, 0121, 0121, 0121, 0111, 0111, /* LT, LE, GT, GE, EQ, NE */
+ 0101, 0071, 0061, 0051, 0041, /* AND, XOR, OR, ANA, ORO */
+ 0031, 0031, /* QUE, COL */
+/* Parens */
+ 0013, 0023 /* RPA, END */
+};
+/*
+ * OP_QUE, OP_RPA and unary operators have alternate precedences:
+ */
+#define OP_RPA_PREC 0013
+#define OP_QUE_PREC 0024 /* From right to left grouping */
+#define OP_UNOP_PREC 0154 /* ditto */
+
+/*
+ * S_ANDOR and S_QUEST signal "short-circuit" boolean evaluation, so that
+ * #if FOO != 0 && 10 / FOO ...
+ * doesn't generate an error message. They are stored in optab.skip.
+ */
+#define S_ANDOR 2
+#define S_QUEST 1
+
+static VAL_SIGN ev; /* Current value and signedness */
+static int skip = 0; /* 3-way signal of skipping expr*/
+static const char * const non_eval
+ = " (in non-evaluated sub-expression)"; /* _W8_ */
+
+#if HAVE_LONG_LONG && COMPILER == INDEPENDENT
+ static int w_level = 1; /* warn_level at overflow of long */
+#else
+ static int w_level = 2;
+#endif
+
+/*
+ * In KR and OLD_PREP modes.
+ * Define bits for the basic types and their adjectives.
+ */
+#define T_CHAR 1
+#define T_INT 2
+#define T_FLOAT 4
+#define T_DOUBLE 8
+#define T_LONGDOUBLE 16
+#define T_SHORT 32
+#define T_LONG 64
+#define T_LONGLONG 128
+#define T_SIGNED 256
+#define T_UNSIGNED 512
+#define T_PTR 1024 /* Pointer to data objects */
+#define T_FPTR 2048 /* Pointer to functions */
+
+/*
+ * The SIZES structure is used to store the values for #if sizeof.
+ */
+typedef struct sizes {
+ int bits; /* If this bit is set, */
+ int size; /* this is the datum size value */
+ int psize; /* this is the pointer size */
+} SIZES;
+
+/*
+ * S_CHAR etc. define the sizeof the basic TARGET machine word types.
+ * By default, sizes are set to the values for the HOST computer. If
+ * this is inappropriate, see those tables for details on what to change.
+ * Also, if you have a machine where sizeof (signed int) differs from
+ * sizeof (unsigned int), you will have to edit those tables and code in
+ * eval.c.
+ * Note: sizeof in #if expression is disallowed by Standard.
+ */
+
+#define S_CHAR (sizeof (char))
+#define S_SINT (sizeof (short int))
+#define S_INT (sizeof (int))
+#define S_LINT (sizeof (long int))
+#define S_FLOAT (sizeof (float))
+#define S_DOUBLE (sizeof (double))
+#define S_PCHAR (sizeof (char *))
+#define S_PSINT (sizeof (short int *))
+#define S_PINT (sizeof (int *))
+#define S_PLINT (sizeof (long int *))
+#define S_PFLOAT (sizeof (float *))
+#define S_PDOUBLE (sizeof (double *))
+#define S_PFPTR (sizeof (int (*)()))
+#if HAVE_LONG_LONG
+#if HOST_COMPILER == BORLANDC
+#define S_LLINT (sizeof (__int64))
+#define S_PLLINT (sizeof (__int64 *))
+#else
+#define S_LLINT (sizeof (long long int))
+#define S_PLLINT (sizeof (long long int *))
+#endif
+#endif
+#define S_LDOUBLE (sizeof (long double))
+#define S_PLDOUBLE (sizeof (long double *))
+
+typedef struct types {
+ int type; /* This is the bits for types */
+ char * token_name; /* this is the token word */
+ int excluded; /* but these aren't legal here. */
+} TYPES;
+
+#define ANYSIGN (T_SIGNED | T_UNSIGNED)
+#define ANYFLOAT (T_FLOAT | T_DOUBLE | T_LONGDOUBLE)
+#if HAVE_LONG_LONG
+#define ANYINT (T_CHAR | T_SHORT | T_INT | T_LONG | T_LONGLONG)
+#else
+#define ANYINT (T_CHAR | T_SHORT | T_INT | T_LONG)
+#endif
+
+static const TYPES basic_types[] = {
+ { T_CHAR, "char", ANYFLOAT | ANYINT },
+ { T_SHORT, "short", ANYFLOAT | ANYINT },
+ { T_INT, "int", ANYFLOAT | T_CHAR | T_INT },
+ { T_LONG, "long", ANYFLOAT | ANYINT },
+#if HAVE_LONG_LONG
+#if HOST_COMPILER == BORLANDC
+ { T_LONGLONG, "__int64", ANYFLOAT | ANYINT },
+#else
+ { T_LONGLONG, "long long", ANYFLOAT | ANYINT },
+#endif
+#endif
+ { T_FLOAT, "float", ANYFLOAT | ANYINT | ANYSIGN },
+ { T_DOUBLE, "double", ANYFLOAT | ANYINT | ANYSIGN },
+ { T_LONGDOUBLE, "long double", ANYFLOAT | ANYINT | ANYSIGN },
+ { T_SIGNED, "signed", ANYFLOAT | ANYINT | ANYSIGN },
+ { T_UNSIGNED, "unsigned", ANYFLOAT | ANYINT | ANYSIGN },
+ { 0, 0, 0 } /* Signal end */
+};
+
+/*
+ * In this table, T_FPTR (pointer to function) should be placed last.
+ */
+static const SIZES size_table[] = {
+ { T_CHAR, S_CHAR, S_PCHAR }, /* char */
+ { T_SHORT, S_SINT, S_PSINT }, /* short int */
+ { T_INT, S_INT, S_PINT }, /* int */
+ { T_LONG, S_LINT, S_PLINT }, /* long */
+#if HAVE_LONG_LONG
+ { T_LONGLONG, S_LLINT, S_PLLINT }, /* long long */
+#endif
+ { T_FLOAT, S_FLOAT, S_PFLOAT }, /* float */
+ { T_DOUBLE, S_DOUBLE, S_PDOUBLE }, /* double */
+ { T_LONGDOUBLE, S_LDOUBLE, S_PLDOUBLE }, /* long double */
+ { T_FPTR, 0, S_PFPTR }, /* int (*()) */
+ { 0, 0, 0 } /* End of table */
+};
+
+#define is_binary(op) (FIRST_BINOP <= op && op <= LAST_BINOP)
+#define is_unary(op) (FIRST_UNOP <= op && op <= LAST_UNOP)
+
+
+#if MCPP_LIB
+void init_eval( void)
+{
+ skip = 0;
+}
+#endif
+
+expr_t eval_if( void)
+/*
+ * Evaluate a #if expression. Straight-forward operator precedence.
+ * This is called from directive() on encountering an #if statement.
+ * It calls the following routines:
+ * eval_lex() Lexical analyser -- returns the type and value of
+ * the next input token.
+ * eval_eval() Evaluates the current operator, given the values on the
+ * value stack. Returns a pointer to the (new) value stack.
+ */
+{
+ VAL_SIGN value[ NEXP * 2 + 1]; /* Value stack */
+ OPTAB opstack[ NEXP * 3 + 1]; /* Operator stack */
+ int parens = 0; /* Nesting levels of (, ) */
+ int prec; /* Operator precedence */
+ int binop = 0; /* Set if binary op. needed */
+ int op1; /* Operator from stack */
+ int skip_cur; /* For short-circuit testing */
+ VAL_SIGN * valp = value; /* -> Value and signedness */
+ OPTAB * opp = opstack; /* -> Operator stack */
+ int op; /* Current operator */
+
+ opp->op = OP_END; /* Mark bottom of stack */
+ opp->prec = opdope[ OP_END]; /* And its precedence */
+ skip = skip_cur = opp->skip = 0; /* Not skipping now */
+
+ while (1) {
+ if (mcpp_debug & EXPRESSION)
+ mcpp_fprintf( DBG
+ , "In eval loop skip = %d, binop = %d, line is: %s\n"
+ , opp->skip, binop, infile->bptr);
+ skip = opp->skip;
+ op = eval_lex();
+ skip = 0; /* Reset to be ready to return */
+ switch (op) {
+ case OP_SUB :
+ if (binop == 0)
+ op = OP_NEG; /* Unary minus */
+ break;
+ case OP_ADD :
+ if (binop == 0)
+ op = OP_PLU; /* Unary plus */
+ break;
+ case OP_FAIL:
+ return 0L; /* Token error */
+ }
+ if (mcpp_debug & EXPRESSION)
+ mcpp_fprintf( DBG
+ , "op = %s, opdope = %04o, binop = %d, skip = %d\n"
+ , opname[ op], opdope[ op], binop, opp->skip);
+ if (op == VAL) { /* Value? */
+ if (binop != 0) { /* Binop is needed */
+ cerror( "Misplaced constant \"%s\"" /* _E_ */
+ , work_buf, 0L, 0);
+ return 0L;
+ } else if (& value[ NEXP * 2] <= valp) {
+ cerror( "More than %.0s%ld constants stacked at %s" /* _E_ */
+ , 0, (long) (NEXP * 2 - 1), work_buf);
+ return 0L;
+ } else {
+ if (mcpp_debug & EXPRESSION) {
+ dump_val( "pushing ", &ev);
+ mcpp_fprintf( DBG, " onto value stack[%d]\n"
+ , (int)(valp - value));
+ }
+ valp->val = ev.val;
+ (valp++)->sign = ev.sign;
+ binop = 1; /* Binary operator or so should follow */
+ }
+ continue;
+ } /* Else operators */
+ prec = opdope[ op];
+ if (binop != (prec & 1)) {
+ if (op == OP_EOE)
+ cerror( "Unterminated expression" /* _E_ */
+ , 0, 0L, 0);
+ else
+ cerror( "Operator \"%s\" in incorrect context" /* _E_ */
+ , opname[ op], 0L, 0);
+ return 0L;
+ }
+ binop = (prec & 2) >> 1; /* Binop should follow? */
+
+ while (1) {
+ if (mcpp_debug & EXPRESSION)
+ mcpp_fprintf( DBG
+ , "op %s, prec %d, stacked op %s, prec %d, skip %d\n"
+ , opname[ op], prec, opname[ static_cast<size_t> (opp->op)], opp->prec, opp->skip);
+
+ /* Stack coming sub-expression of higher precedence. */
+ if (opp->prec < prec) {
+ if (op == OP_LPA) {
+ prec = OP_RPA_PREC;
+ if (standard && (warn_level & 4)
+ && ++parens == exp_nest_min + 1)
+ cwarn(
+ "More than %.0s%ld nesting of parens" /* _W4_ */
+ , 0, (long) exp_nest_min, 0);
+ } else if (op == OP_QUE) {
+ prec = OP_QUE_PREC;
+ } else if (is_unary( op)) {
+ prec = OP_UNOP_PREC;
+ }
+ op1 = opp->skip; /* Save skip for test */
+ /*
+ * Push operator onto operator stack.
+ */
+ opp++;
+ if (& opstack[ NEXP * 3] <= opp) {
+ cerror(
+ "More than %.0s%ld operators and parens stacked at %s" /* _E_ */
+ , 0, (long) (NEXP * 3 - 1), opname[ op]);
+ return 0L;
+ }
+ opp->op = op;
+ opp->prec = prec;
+ if (&value[0] < valp)
+ skip_cur = (valp[-1].val != 0L);
+ /* Short-circuit tester */
+ /*
+ * Do the short-circuit stuff here. Short-circuiting
+ * stops automagically when operators are evaluated.
+ */
+ if ((op == OP_ANA && ! skip_cur)
+ || (op == OP_ORO && skip_cur)) {
+ opp->skip = S_ANDOR; /* And/or skip starts */
+ if (skip_cur) /* Evaluate non-zero */
+ valp[-1].val = 1L; /* value to 1 */
+ } else if (op == OP_QUE) { /* Start of ?: operator */
+ opp->skip = (op1 & S_ANDOR) | (!skip_cur ? S_QUEST : 0);
+ } else if (op == OP_COL) { /* : inverts S_QUEST */
+ opp->skip = (op1 & S_ANDOR)
+ | (((op1 & S_QUEST) != 0) ? 0 : S_QUEST);
+ } else { /* Other operators leave*/
+ opp->skip = op1; /* skipping unchanged. */
+ }
+ if (mcpp_debug & EXPRESSION) {
+ mcpp_fprintf( DBG, "stacking %s, ", opname[ op]);
+ if (&value[0] < valp)
+ dump_val( "valp[-1].val == ", valp - 1);
+ mcpp_fprintf( DBG, " at %s\n", infile->bptr);
+ dump_stack( opstack, opp, value, valp);
+ }
+ break;
+ }
+
+ /*
+ * Coming sub-expression is of lower precedence.
+ * Evaluate stacked sub-expression.
+ * Pop operator from operator stack and evaluate it.
+ * End of stack and '(', ')' are specials.
+ */
+ skip_cur = opp->skip; /* Remember skip value */
+ switch ((op1 = opp->op)) { /* Look at stacked op */
+ case OP_END: /* Stack end marker */
+ if (op == OP_RPA) { /* No corresponding ( */
+ cerror( "Excessive \")\"", 0, 0L, 0); /* _E_ */
+ return 0L;
+ }
+ if (op == OP_EOE)
+ return valp[-1].val; /* Finished ok. */
+ break;
+ case OP_LPA: /* ( on stack */
+ if (op != OP_RPA) { /* Matches ) on input? */
+ cerror( "Missing \")\"", 0, 0L, 0); /* _E_ */
+ return 0L;
+ }
+ opp--; /* Unstack it */
+ parens--; /* Count down nest level*/
+ break;
+ case OP_QUE: /* Evaluate true expr. */
+ break;
+ case OP_COL: /* : on stack */
+ opp--; /* Unstack : */
+ if (opp->op != OP_QUE) { /* Matches ? on stack? */
+ cerror(
+ "Misplaced \":\", previous operator is \"%s\"" /* _E_ */
+ , opname[static_cast<size_t> (opp->op)], 0L, 0);
+ return 0L;
+ }
+ /* Evaluate op1. Fall through */
+ default: /* Others: */
+ opp--; /* Unstack the operator */
+ if (mcpp_debug & EXPRESSION) {
+ mcpp_fprintf( DBG, "Stack before evaluation of %s\n"
+ , opname[ op1]);
+ dump_stack( opstack, opp, value, valp);
+ }
+ if (op1 == OP_COL)
+ skip = 0;
+ else
+ skip = skip_cur;
+ valp = eval_eval( valp, op1);
+ if (valp->sign == VAL_ERROR)
+ return 0L; /* Out of range or divide by 0 */
+ valp++;
+ skip = 0;
+ if (mcpp_debug & EXPRESSION) {
+ mcpp_fprintf( DBG, "Stack after evaluation\n");
+ dump_stack( opstack, opp, value, valp);
+ }
+ } /* op1 switch end */
+
+ if (op1 == OP_END || op1 == OP_LPA || op1 == OP_QUE)
+ break; /* Read another op. */
+ } /* Stack unwind loop */
+
+ }
+
+ return 0L; /* Never reach here */
+}
+
+static int eval_lex( void)
+/*
+ * Return next operator or value to evaluate. Called from eval_if(). It calls
+ * a special-purpose routines for character constants and numeric values:
+ * eval_char() called to evaluate 'x'
+ * eval_num() called to evaluate numbers
+ * C++98 treats 11 identifier-like tokens as operators.
+ * POST_STD forbids character constants in #if expression.
+ */
+{
+ int c1;
+ VAL_SIGN * valp;
+ int warn = ! skip || (warn_level & 8);
+ int token_type;
+ int c;
+
+ ev.sign = SIGNED; /* Default signedness */
+ ev.val = 0L; /* Default value (on error or 0 value) */
+ c = skip_ws();
+ if (c == '\n') {
+ unget_ch();
+ return OP_EOE; /* End of expression */
+ }
+ token_type = get_unexpandable( c, warn);
+ if (standard && macro_line == MACRO_ERROR)
+ return OP_FAIL; /* Unterminated macro call */
+ if (token_type == NO_TOKEN)
+ return OP_EOE; /* Only macro(s) expanding to 0-token */
+
+ switch (token_type) {
+ case NAM:
+ if (standard && str_eq( identifier, "defined")) { /* defined name */
+ c1 = c = skip_ws();
+ if (c == '(') /* Allow defined (name) */
+ c = skip_ws();
+ if (scan_token( c, (workp = work_buf, &workp), work_end) == NAM) {
+ if (warn)
+ ev.val = (look_id( identifier) != 0);
+ if (c1 != '(' || skip_ws() == ')') /* Balanced ? */
+ return VAL; /* Parsed ok */
+ }
+ cerror( "Bad defined syntax: %s" /* _E_ */
+ , infile->fp ? "" : infile->buffer, 0L, 0);
+ break;
+ } else if (cplus_val) {
+ if (str_eq( identifier, "true")) {
+ ev.val = 1L;
+ return VAL;
+ } else if (str_eq( identifier, "false")) {
+ ev.val = 0L;
+ return VAL;
+ } else if (mcpp_mode != POST_STD
+ && (openum = id_operator( identifier)) != 0) {
+ /* Identifier-like operator in C++98 */
+ ACE_OS::strcpy( work_buf, identifier);
+ return chk_ops();
+ }
+ } else if (! standard && str_eq( identifier, "sizeof")) {
+ /* sizeof hackery */
+ return do_sizeof(); /* Gets own routine */
+ }
+ /*
+ * The ANSI C Standard says that an undefined symbol
+ * in an #if has the value zero. We are a bit pickier,
+ * warning except where the programmer was careful to write
+ * #if defined(foo) ? foo : 0
+ */
+ if ((! skip && (warn_level & 4)) || (skip && (warn_level & 8)))
+ cwarn( "Undefined symbol \"%s\"%.0ld%s" /* _W4_ _W8_ */
+ , identifier, 0L, skip ? non_eval : ", evaluated to 0");
+ return VAL;
+ case CHR: /* Character constant */
+ case WCHR: /* Wide char constant */
+ if (mcpp_mode == POST_STD) {
+ cerror( "Can't use a character constant %s" /* _E_ */
+ , work_buf, 0L, 0);
+ break;
+ }
+ valp = eval_char( work_buf); /* 'valp' points 'ev' */
+ if (valp->sign == VAL_ERROR)
+ break;
+ if (mcpp_debug & EXPRESSION) {
+ dump_val( "eval_char returns ", &ev);
+ mcpp_fputc( '\n', DBG);
+ }
+ return VAL; /* Return a value */
+ case STR: /* String literal */
+ case WSTR: /* Wide string literal */
+ cerror(
+ "Can't use a string literal %s", work_buf, 0L, 0); /* _E_ */
+ break;
+ case NUM: /* Numbers are harder */
+ valp = eval_num( work_buf); /* 'valp' points 'ev' */
+ if (valp->sign == VAL_ERROR)
+ break;
+ if (mcpp_debug & EXPRESSION) {
+ dump_val( "eval_num returns ", &ev);
+ mcpp_fputc( '\n', DBG);
+ }
+ return VAL;
+ case OPE: /* Operator or punctuator */
+ return chk_ops();
+
+ default: /* Total nonsense */
+ cerror( "Can't use the character %.0s0x%02lx" /* _E_ */
+ , 0, (long) c, 0);
+ break;
+ }
+
+ return OP_FAIL; /* Any errors */
+}
+
+static int chk_ops( void)
+/*
+ * Check the operator.
+ * If it can't be used in #if expression return OP_FAIL
+ * else return openum.
+ */
+{
+ switch (openum) {
+ case OP_STR: case OP_CAT: case OP_ELL:
+ case OP_1: case OP_2: case OP_3:
+ cerror( "Can't use the operator \"%s\"" /* _E_ */
+ , work_buf, 0L, 0);
+ return OP_FAIL;
+ default:
+ return openum;
+ }
+}
+
+static int do_sizeof( void)
+/*
+ * Process the sizeof (basic type) operation in an #if string.
+ * Sets ev.val to the size and returns
+ * VAL success
+ * OP_FAIL bad parse or something.
+ * This routine is never called in STD and POST_STD mode.
+ */
+{
+ const char * const no_type = "sizeof: No type specified"; /* _E_ */
+ int warn = ! skip || (warn_level & 8);
+ int type_end = FALSE;
+ int typecode = 0;
+ int token_type = NO_TOKEN;
+ const SIZES * sizp = 0;
+
+ if (get_unexpandable( skip_ws(), warn) != OPE || openum != OP_LPA)
+ goto no_good; /* Not '(' */
+
+ /*
+ * Scan off the tokens.
+ */
+
+ while (! type_end) {
+ token_type = get_unexpandable( skip_ws(), warn);
+ /* Get next token expanding macros */
+ switch (token_type) {
+ case OPE:
+ if (openum == OP_LPA) { /* thing (*)() func ptr */
+ if (get_unexpandable( skip_ws(), warn) == OPE
+ && openum == OP_MUL
+ && get_unexpandable( skip_ws(), warn) == OPE
+ && openum == OP_RPA) { /* (*) */
+ if (get_unexpandable( skip_ws(), warn) != OPE
+ || openum != OP_LPA
+ || get_unexpandable( skip_ws(), warn) != OPE
+ || openum != OP_RPA) /* Not () */
+ goto no_good;
+ typecode |= T_FPTR; /* Function pointer */
+ } else { /* Junk is an error */
+ goto no_good;
+ }
+ } else { /* '*' or ')' */
+ type_end = TRUE;
+ }
+ break;
+ case NAM: /* Look for type comb. */
+ if ((typecode = look_type( typecode)) == 0)
+ return OP_FAIL; /* Illegal type or comb.*/
+ break;
+ default: goto no_good; /* Illegal token */
+ }
+ } /* End of while */
+
+ /*
+ * We are at the end of the type scan. Chew off '*' if necessary.
+ */
+ if (token_type == OPE) {
+ if (openum == OP_MUL) { /* '*' */
+ typecode |= T_PTR;
+ if (get_unexpandable( skip_ws(), warn) != OPE)
+ goto no_good;
+ }
+ if (openum == OP_RPA) { /* ')' */
+ /*
+ * Last syntax check
+ * We assume that all function pointers are the same size:
+ * sizeof (int (*)()) == sizeof (float (*)())
+ * We assume that signed and unsigned don't change the size:
+ * sizeof (signed int) == sizeof (unsigned int)
+ */
+ if ((typecode & T_FPTR) != 0) { /* Function pointer */
+ typecode = T_FPTR | T_PTR;
+ } else { /* Var or var * datum */
+ typecode &= ~(T_SIGNED | T_UNSIGNED);
+#if HAVE_LONG_LONG
+ if ((typecode & (T_SHORT | T_LONG | T_LONGLONG)) != 0)
+#else
+ if ((typecode & (T_SHORT | T_LONG)) != 0)
+#endif
+ typecode &= ~T_INT;
+ }
+ if ((typecode & ~T_PTR) == 0) {
+ cerror( no_type, 0, 0L, 0);
+ return OP_FAIL;
+ } else {
+ /*
+ * Exactly one bit (and possibly T_PTR) may be set.
+ */
+ for (sizp = size_table; sizp->bits != 0; sizp++) {
+ if ((typecode & ~T_PTR) == sizp->bits) {
+ ev.val = ((typecode & T_PTR) != 0)
+ ? sizp->psize : sizp->size;
+ break;
+ }
+ }
+ }
+ } else {
+ goto no_good;
+ }
+ } else {
+ goto no_good;
+ }
+
+ if (mcpp_debug & EXPRESSION) {
+ if (sizp)
+ mcpp_fprintf( DBG,
+ "sizp->bits:0x%x sizp->size:0x%x sizp->psize:0x%x ev.val:0x%lx\n"
+ , sizp->bits, sizp->size, sizp->psize
+ , (unsigned long) ev.val);
+ }
+ return VAL;
+
+no_good:
+ unget_ch();
+ cerror( "sizeof: Syntax error", 0, 0L, 0); /* _E_ */
+ return OP_FAIL;
+}
+
+static int look_type(
+ int typecode
+)
+{
+ const char * const unknown_type
+ = "sizeof: Unknown type \"%s\"%.0ld%s"; /* _E_ _W8_ */
+ const char * const illeg_comb
+ = "sizeof: Illegal type combination with \"%s\"%.0ld%s"; /* _E_ _W8_ */
+ int token_type;
+ const TYPES * tp;
+
+ if (str_eq( identifier, "long")) {
+ if ((token_type
+ = get_unexpandable( skip_ws(), !skip || (warn_level & 8)))
+ == NO_TOKEN)
+ return typecode;
+ if (token_type == NAM) {
+#if HAVE_LONG_LONG
+ if (str_eq( identifier, "long")) {
+ ACE_OS::strcpy( work_buf, "long long");
+ goto basic;
+ }
+#endif
+ if (str_eq( identifier, "double")) {
+ ACE_OS::strcpy( work_buf, "long double");
+ goto basic;
+ }
+ }
+ unget_string( work_buf, 0); /* Not long long */
+ ACE_OS::strcpy( work_buf, "long"); /* nor long double */
+ }
+
+ /*
+ * Look for this unexpandable token in basic_types.
+ */
+basic:
+ for (tp = basic_types; tp->token_name != 0; tp++) {
+ if (str_eq( work_buf, tp->token_name))
+ break;
+ }
+
+ if (tp->token_name == 0) {
+ if (! skip) {
+ cerror( unknown_type, work_buf, 0L, 0);
+ return 0;
+ } else if (warn_level & 8) {
+ cwarn( unknown_type, work_buf, 0L, non_eval);
+ }
+ }
+ if ((typecode & tp->excluded) != 0) {
+ if (! skip) {
+ cerror( illeg_comb, work_buf, 0L, 0);
+ return 0;
+ } else if (warn_level & 8) {
+ cwarn( illeg_comb, work_buf, 0L, non_eval);
+ }
+ }
+
+ if (mcpp_debug & EXPRESSION) {
+ if (tp->token_name)
+ mcpp_fprintf( DBG,
+ "sizeof -- typecode:0x%x tp->token_name:\"%s\" tp->type:0x%x\n"
+ , typecode, tp->token_name, tp->type);
+ }
+ return typecode |= tp->type; /* Or in the type bit */
+}
+
+VAL_SIGN * eval_num(
+ const char * nump /* Preprocessing number */
+)
+/*
+ * Evaluate number for #if lexical analysis. Note: eval_num recognizes
+ * the unsigned suffix, but only returns a signed expr_t value, and stores
+ * the signedness to ev.sign, which is set UNSIGNED (== unsigned) if the
+ * value is not in the range of positive (signed) expr_t.
+ */
+{
+ const char * const not_integer = "Not an integer \"%s\""; /* _E_ */
+ const char * const out_of_range
+ = "Constant \"%s\"%.0ld%s is out of range"; /* _E_ _W1_ _W8_ */
+ expr_t value;
+ uexpr_t v, v1; /* unsigned long long or unsigned long */
+ int uflag = FALSE;
+ int lflag = FALSE;
+ int erange = FALSE;
+ int base;
+ int c, c1;
+ const char * cp = nump;
+#if HAVE_LONG_LONG
+ const char * const out_of_range_long =
+ "Constant \"%s\"%.0ld%s is out of range " /* _E_ _W1_ _W2_ _W8_ */
+ "of (unsigned) long";
+ const char * const ll_suffix =
+"LL suffix is used in other than C99 mode \"%s\"%.0ld%s"; /* _W1_ _W2_ _W8_ */
+#if COMPILER == MSC || COMPILER == BORLANDC
+ const char * const i64_suffix =
+"I64 suffix is used in other than C99 mode \"%s\"%.0ld%s"; /* _W2_ _W8_ */
+#endif
+ int llflag = FALSE;
+ int erange_long = FALSE;
+#endif
+
+ ev.sign = SIGNED; /* Default signedness */
+ ev.val = 0L; /* Default value */
+ if ((char_type[ c = *cp++ & UCHARMAX] & DIG) == 0) /* Dot */
+ goto num_err;
+ if (c != '0') { /* Decimal */
+ base = 10;
+ } else if ((c = *cp++ & UCHARMAX) == 'x' || c == 'X') {
+ base = 16; /* Hexadecimal */
+ c = *cp++ & UCHARMAX;
+ } else if (c == EOS) { /* 0 */
+ return & ev;
+ } else { /* Octal or illegal */
+ base = 8;
+ }
+
+ v = v1 = 0L;
+ for (;;) {
+ c1 = c;
+ if (ACE_OS::ace_isupper( c1))
+ c1 = ACE_OS::ace_tolower( c1);
+ if (c1 >= 'a')
+ c1 -= ('a' - 10);
+ else
+ c1 -= '0';
+ if (c1 < 0 || base <= c1)
+ break;
+ v1 *= base;
+ v1 += c1;
+ if (v1 / base < v) { /* Overflow */
+ if (! skip)
+ goto range_err;
+ else
+ erange = TRUE;
+ }
+#if HAVE_LONG_LONG
+ if (! stdc3 && v1 > ULONGMAX)
+ /* Overflow of long or unsigned long */
+ erange_long = TRUE;
+#endif
+ v = v1;
+ c = *cp++ & UCHARMAX;
+ }
+
+ value = v;
+ while (c == 'u' || c == 'U' || c == 'l' || c == 'L') {
+ if (c == 'u' || c == 'U') {
+ if (uflag)
+ goto num_err;
+ uflag = TRUE;
+ } else if (c == 'l' || c == 'L') {
+#if HAVE_LONG_LONG
+ if (llflag) {
+ goto num_err;
+ } else if (lflag) {
+ llflag = TRUE;
+ if (! stdc3 && ((! skip && (warn_level & w_level))
+ || (skip && (warn_level & 8))))
+ cwarn( ll_suffix, nump, 0L, skip ? non_eval : 0);
+ } else {
+ lflag = TRUE;
+ }
+#else
+ if (lflag)
+ goto num_err;
+ else
+ lflag = TRUE;
+#endif
+ }
+ c = *cp++;
+ }
+#if HAVE_LONG_LONG && (COMPILER == MSC || COMPILER == BORLANDC)
+ if (ACE_OS::ace_tolower( c) == 'i') {
+ c1 = ACE_OS::atoi( cp);
+ if (c1 == 64) {
+ if (! stdc3 && ((! skip && (warn_level & w_level))
+ || (skip && (warn_level & 8))))
+ cwarn( i64_suffix, nump, 0L, skip ? non_eval : 0);
+ cp += 2;
+ } else if (c1 == 32 || c1 == 16) {
+ cp += 2;
+ } else if (c1 == 8) {
+ cp++;
+ }
+ c = *cp++;
+ }
+#endif
+
+ if (c != EOS)
+ goto num_err;
+
+ if (standard) {
+ if (uflag) /* If 'U' suffixed, uexpr_t is treated as unsigned */
+ ev.sign = UNSIGNED;
+ else
+ ev.sign = (value >= 0L);
+#if HAVE_LONG_LONG
+ } else {
+ if (value > LONGMAX)
+ erange_long = TRUE;
+#endif
+ }
+
+ ev.val = value;
+ if (erange && (warn_level & 8))
+ cwarn( out_of_range, nump, 0L, non_eval);
+#if HAVE_LONG_LONG
+ else if (erange_long && ((skip && (warn_level & 8))
+ || (! stdc3 && ! skip && (warn_level & w_level))))
+ cwarn( out_of_range_long, nump, 0L, skip ? non_eval : 0);
+#endif
+ return & ev;
+
+range_err:
+ cerror( out_of_range, nump, 0L, 0);
+ ev.sign = VAL_ERROR;
+ return & ev;
+num_err:
+ cerror( not_integer, nump, 0L, 0);
+ ev.sign = VAL_ERROR;
+ return & ev;
+}
+
+static VAL_SIGN * eval_char(
+ char * const token
+)
+/*
+ * Evaluate a character constant.
+ * This routine is never called in POST_STD mode.
+ */
+{
+ const char * const w_out_of_range
+ = "Wide character constant %s%.0ld%s is out of range"; /* _E_ _W8_ */
+ const char * const c_out_of_range
+ = "Integer character constant %s%.0ld%s is out of range"; /* _E_ _W8_ */
+ uexpr_t value;
+ uexpr_t tmp;
+ expr_t cl;
+ int erange = FALSE;
+ int wide = (*token == 'L');
+ int ucn8;
+ int i;
+ int bits, mbits, u8bits, bits_save;
+ char * cp = token + 1; /* Character content */
+#if HAVE_LONG_LONG
+ const char * const w_out_of_range_long =
+ "Wide character constant %s%.0ld%s is " /* _E_ _W1_ _W2_ _W8_ */
+ "out of range of unsigned long";
+ const char * const c_out_of_range_long =
+ "Integer character constant %s%.0ld%s is " /* _E_ _W1_ _W2_ _W8_ */
+ "out of range of unsigned long";
+ int erange_long = FALSE;
+#endif
+
+ bits = CHARBIT;
+ u8bits = CHARBIT * 4;
+ if (mbchar & UTF8)
+ mbits = CHARBIT * 4;
+ else
+ mbits = CHARBIT * 2;
+ if (mcpp_mode == STD && wide) { /* Wide character constant */
+ cp++; /* Skip 'L' */
+ bits = mbits;
+ }
+ if (char_type[ *cp & UCHARMAX] & mbstart) {
+ cl = mb_eval( &cp);
+ bits = mbits;
+ } else if ((cl = eval_one( &cp, wide, mbits, (ucn8 = FALSE, &ucn8)))
+ == -1L) {
+ ev.sign = VAL_ERROR;
+ return & ev;
+ }
+ bits_save = bits;
+ value = cl;
+
+ for (i = 0; *cp != '\'' && *cp != EOS; i++) {
+ if (char_type[ *cp & UCHARMAX] & mbstart) {
+ cl = mb_eval( &cp);
+ if (cl == 0)
+ /* Shift-out sequence of multi-byte or wide character */
+ continue;
+ bits = mbits;
+ } else {
+ cl = eval_one( &cp, wide, mbits, (ucn8 = FALSE, &ucn8));
+ if (cl == -1L) {
+ ev.sign = VAL_ERROR;
+ return & ev;
+ }
+#if OK_UCN
+ if (ucn8 == TRUE)
+ bits = u8bits;
+ else
+ bits = bits_save;
+#endif
+ }
+ tmp = value;
+ value = (value << bits) | cl; /* Multi-char or multi-byte char */
+ if ((value >> bits) < tmp) { /* Overflow */
+ if (! skip)
+ goto range_err;
+ else
+ erange = TRUE;
+ }
+#if HAVE_LONG_LONG
+ if ((mcpp_mode == STD && (! stdc3 && value > ULONGMAX))
+ || (! standard && value > LONGMAX))
+ erange_long = TRUE;
+#endif
+ }
+
+ ev.sign = ((expr_t) value >= 0L);
+ ev.val = value;
+
+ if (erange && skip && (warn_level & 8)) {
+ if (wide)
+ cwarn( w_out_of_range, token, 0L, non_eval);
+ else
+ cwarn( c_out_of_range, token, 0L, non_eval);
+#if HAVE_LONG_LONG
+ } else if (erange_long && ((skip && (warn_level & 8))
+ || (! stdc3 && ! skip && (warn_level & w_level)))) {
+ if (wide)
+ cwarn( w_out_of_range_long, token, 0L, skip ? non_eval : 0);
+ else
+ cwarn( c_out_of_range_long, token, 0L, skip ? non_eval : 0);
+#endif
+ }
+
+ if (i == 0) /* Constant of single (character or wide-character) */
+ return & ev;
+
+ if ((! skip && (warn_level & 4)) || (skip && (warn_level & 8))) {
+ if (mcpp_mode == STD && wide)
+ cwarn(
+"Multi-character wide character constant %s%.0ld%s isn't portable" /* _W4_ _W8_ */
+ , token, 0L, skip ? non_eval : 0);
+ else
+ cwarn(
+"Multi-character or multi-byte character constant %s%.0ld%s isn't portable" /* _W4_ _W8_ */
+ , token, 0L, skip ? non_eval : 0);
+ }
+ return & ev;
+
+range_err:
+ if (wide)
+ cerror( w_out_of_range, token, 0L, 0);
+ else
+ cerror( c_out_of_range, token, 0L, 0);
+ ev.sign = VAL_ERROR;
+ return & ev;
+}
+
+static expr_t eval_one(
+ char ** seq_pp, /* Address of pointer to sequence */
+ /* eval_one() advances the pointer to sequence */
+ int wide, /* Flag of wide-character */
+ int mbits, /* Number of bits of a wide-char */
+ int * ucn8 /* Flag of UCN-32 bits */
+)
+/*
+ * Called from eval_char() above to get a single character, single multi-
+ * byte character or wide character (with or without \ escapes).
+ * Returns the value of the character or -1L on error.
+ */
+{
+#if OK_UCN
+ const char * const ucn_malval
+ = "UCN cannot specify the value %.0s\"%08lx\""; /* _E_ _W8_ */
+#endif
+ const char * const out_of_range
+ = "%s%ld bits can't represent escape sequence '%s'"; /* _E_ _W8_ */
+ uexpr_t value;
+ int erange = FALSE;
+ char * seq = *seq_pp; /* Initial seq_pp for diagnostic*/
+ const char * cp;
+ const char * digits;
+ unsigned uc;
+ unsigned uc1;
+ int count;
+ int bits;
+ size_t wchar_max;
+
+ uc = *(*seq_pp)++ & UCHARMAX;
+
+ if (uc != '\\') /* Other than escape sequence */
+ return (expr_t) uc;
+
+ /* escape sequence */
+ uc1 = uc = *(*seq_pp)++ & UCHARMAX;
+ switch (uc) {
+ case 'a':
+ return '\a';
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 't':
+ return '\t';
+ case 'v':
+ return '\v';
+#if OK_UCN
+ case 'u': case 'U':
+ if (! stdc2)
+ goto undefined;
+ /* Else Universal character name */
+ /* Fall through */
+#endif
+ case 'x': /* '\xFF' */
+ if (! standard)
+ goto undefined;
+ digits = "0123456789abcdef";
+ bits = 4;
+ uc = *(*seq_pp)++ & UCHARMAX;
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ digits = "01234567";
+ bits = 3;
+ break;
+ case '\'': case '"': case '?': case '\\':
+ return (expr_t) uc;
+ default:
+ goto undefined;
+ }
+
+ wchar_max = (UCHARMAX << CHARBIT) | UCHARMAX;
+ if (mbits == CHARBIT * 4) {
+ if (mcpp_mode == STD)
+ wchar_max = (wchar_max << CHARBIT * 2) | wchar_max;
+ else
+ wchar_max = LONGMAX;
+ }
+
+ value = 0L;
+ for (count = 0; ; ++count) {
+ if (ACE_OS::ace_isupper( uc))
+ uc = ACE_OS::ace_tolower( uc);
+ if ((cp = ACE_OS::strchr( digits, uc)) == 0)
+ break;
+ if (count >= 3 && bits == 3)
+ break; /* Octal escape sequence at most 3 digits */
+#if OK_UCN
+ if ((count >= 4 && uc1 == 'u') || (count >= 8 && uc1 == 'U'))
+ break;
+#endif
+ value = (value << bits) | (cp - digits);
+#if OK_UCN
+ if (wchar_max < value && uc1 != 'u' && uc1 != 'U')
+#else
+ if (wchar_max < value)
+#endif
+ {
+ if (! skip)
+ goto range_err;
+ else
+ erange = TRUE;
+ }
+ uc = *(*seq_pp)++ & UCHARMAX;
+ }
+ (*seq_pp)--;
+
+ if (erange) {
+ value &= wchar_max;
+ goto range_err;
+ }
+
+ if (count == 0 && bits == 4) /* '\xnonsense' */
+ goto undefined;
+#if OK_UCN
+ if (uc1 == 'u' || uc1 == 'U') {
+ if ((count < 4 && uc1 == 'u') || (count < 8 && uc1 == 'U'))
+ goto undefined;
+ if ((/*value >= 0L &&*/ value <= 0x9FL
+ && value != 0x24L && value != 0x40L && value != 0x60L)
+ || (!stdc3 && value >= 0xD800L && value <= 0xDFFFL)) {
+ if (!skip)
+ cerror( ucn_malval, 0, (long) value, 0);
+ else if (warn_level & 8)
+ cwarn( ucn_malval, 0, (long) value, 0);
+ }
+ if (count >= 8 && uc1 == 'U')
+ *ucn8 = TRUE;
+ return (expr_t) value;
+ }
+#endif /* OK_UCN */
+ if (! wide && (UCHARMAX < value)) {
+ value &= UCHARMAX;
+ goto range_err;
+ }
+ return (expr_t) value;
+
+undefined:
+ uc1 = **seq_pp;
+ **seq_pp = EOS; /* For diagnostic */
+ if ((! skip && (warn_level & 1)) || (skip && (warn_level & 8)))
+ cwarn(
+ "Undefined escape sequence%s %.0ld'%s'" /* _W1_ _W8_ */
+ , skip ? non_eval : 0, 0L, seq);
+ **seq_pp = uc1;
+ *seq_pp = seq + 1;
+ return (expr_t) '\\'; /* Returns the escape char */
+
+range_err:
+ uc1 = **seq_pp;
+ **seq_pp = EOS; /* For diagnostic */
+ if (wide) {
+ if (! skip)
+ cerror( out_of_range, 0, (long) mbits, seq);
+ else if (warn_level & 8)
+ cwarn( out_of_range, non_eval, (long) mbits, seq);
+ } else {
+ if (! skip)
+ cerror( out_of_range, 0, (long) CHARBIT, seq);
+ else if (warn_level & 8)
+ cwarn( out_of_range, non_eval, (long) CHARBIT, seq);
+ }
+
+ **seq_pp = uc1;
+ if (! skip)
+ return -1L;
+ else
+ return (expr_t) value;
+}
+
+static VAL_SIGN * eval_eval(
+ VAL_SIGN * valp,
+ int op
+)
+/*
+ * One or two values are popped from the value stack and do arithmetic.
+ * The result is pushed onto the value stack.
+ * eval_eval() returns the new pointer to the top of the value stack.
+ */
+{
+ const char * const zero_div = "%sDivision by zero%.0ld%s"; /* _E_ _W8_ */
+#if HAVE_LONG_LONG
+ const char * const neg_format =
+"Negative value \"%" LL_FORM "d\" is converted to positive \"%" /* _W1_ _W8_*/
+ LL_FORM "u\"%%s";
+#else
+ const char * const neg_format =
+"Negative value \"%ld\" is converted to positive \"%lu\"%%s"; /* _W1_ _W8_*/
+#endif
+ expr_t v1, v2;
+ int sign1, sign2;
+
+ if (is_binary( op)) {
+ v2 = (--valp)->val;
+ sign2 = valp->sign;
+ } else {
+ v2 = 0L; /* Dummy */
+ sign2 = SIGNED; /* Dummy */
+ }
+ v1 = (--valp)->val;
+ sign1 = valp->sign;
+ if (mcpp_debug & EXPRESSION) {
+ mcpp_fprintf( DBG, "%s op %s", (is_binary( op)) ? "binary" : "unary"
+ , opname[ op]);
+ dump_val( ", v1 = ", valp);
+ if (is_binary( op))
+ dump_val( ", v2 = ", valp + 1);
+ mcpp_fputc( '\n', DBG);
+ }
+
+ if (standard
+ && (sign1 == UNSIGNED || sign2 == UNSIGNED) && is_binary( op)
+ && op != OP_ANA && op != OP_ORO && op != OP_SR && op != OP_SL) {
+ if (((sign1 == SIGNED && v1 < 0L) || (sign2 == SIGNED && v2 < 0L)
+ ) && ((! skip && (warn_level & 1))
+ || (skip && (warn_level & 8)))) {
+ char negate[(((sizeof (expr_t) * 8) / 3) + 1) * 2 + 50];
+ expr_t v3;
+
+ v3 = (sign1 == SIGNED ? v1 : v2);
+ ACE_OS::sprintf( negate, neg_format, v3, v3);
+ cwarn( negate, skip ? non_eval : 0, 0L, 0);
+ }
+ valp->sign = sign1 = sign2 = UNSIGNED;
+ }
+ if ((op == OP_SL || op == OP_SR)
+ && ((! skip && (warn_level & 1)) || (skip && (warn_level & 8)))) {
+ if (v2 < 0L || v2 >= sizeof (expr_t) * CHARBIT)
+ cwarn( "Illegal shift count %.0s\"%ld\"%s" /* _W1_ _W8_ */
+ , 0, (long) v2, skip ? non_eval : 0);
+#if HAVE_LONG_LONG
+ else if (! stdc3 && v2 >= sizeof (long) * CHARBIT
+ && ((! skip && (warn_level & w_level))
+ || (skip && (warn_level & 8))))
+ cwarn(
+"Shift count %.0s\"%ld\" is larger than bit count of long%s" /* _W1_ _W8_*/
+ , 0, (long) v2, skip ? non_eval : 0);
+#endif
+ }
+ if ((op == OP_DIV || op == OP_MOD) && v2 == 0L) {
+ if (! skip) {
+ cerror( zero_div, 0, 0L, 0);
+ valp->sign = VAL_ERROR;
+ return valp;
+ } else {
+ if (warn_level & 8)
+ cwarn( zero_div, 0, 0L, non_eval);
+ valp->sign = sign1;
+ valp->val = (expr_t) EXPR_MAX;
+ return valp;
+ }
+ }
+
+ if (! standard || sign1 == SIGNED)
+ v1 = eval_signed( & valp, v1, v2, op);
+ else
+ v1 = eval_unsigned( & valp, (uexpr_t) v1, (uexpr_t) v2, op);
+
+ if (valp->sign == VAL_ERROR) /* Out of range */
+ return valp;
+
+ switch (op) {
+ case OP_NOT: case OP_EQ: case OP_NE:
+ case OP_LT: case OP_LE: case OP_GT: case OP_GE:
+ case OP_ANA: case OP_ORO:
+ valp->sign = SIGNED;
+ break;
+ default:
+ valp->sign = sign1;
+ break;
+ }
+ valp->val = v1;
+ return valp;
+}
+
+static expr_t eval_signed(
+ VAL_SIGN ** valpp,
+ expr_t v1,
+ expr_t v2,
+ int op
+)
+/*
+ * Apply the argument operator to the signed data.
+ * OP_COL is a special case.
+ */
+{
+ const char * const illeg_op
+ = "Bug: Illegal operator \"%s\" in eval_signed()"; /* _F_ */
+ const char * const not_portable
+ = "\"%s\" of negative number isn't portable%.0ld%s"; /* _W1_ _W8_*/
+ const char * op_name = opname[ op];
+ VAL_SIGN * valp = *valpp;
+ expr_t val;
+ int chk; /* Flag of overflow in long long */
+
+ switch (op) {
+ case OP_EOE:
+ case OP_PLU: break;
+ case OP_NEG:
+ chk = v1 && v1 == -v1;
+ if (chk
+#if HAVE_LONG_LONG
+ || (! stdc3 && v1 && (long) v1 == (long) -v1)
+#endif
+ )
+ overflow( op_name, valpp, chk);
+ v1 = -v1;
+ break;
+ case OP_COM: v1 = ~v1; break;
+ case OP_NOT: v1 = !v1; break;
+ case OP_MUL:
+ val = v1 * v2;
+ chk = v1 && v2 && (val / v1 != v2 || val / v2 != v1);
+ if (chk
+#if HAVE_LONG_LONG
+ || (! stdc3 && v1 && v2
+ && ((long)val / (long)v1 != (long)v2
+ || (long)val / (long)v2 != (long)v1))
+#endif
+ )
+ overflow( op_name, valpp, chk);
+ v1 = val;
+ break;
+ case OP_DIV:
+ case OP_MOD:
+ /* Division by 0 has been already diagnosed by eval_eval(). */
+ chk = -v1 == v1 && v2 == -1;
+ if (chk /* LONG_MIN / -1 on two's complement */
+#if HAVE_LONG_LONG
+ || (! stdc3
+ && (long)-v1 == (long)v1 && (long)v2 == (long)-1)
+#endif
+ )
+ overflow( op_name, valpp, chk);
+ else if (! stdc3 && (v1 < 0L || v2 < 0L)
+ && ((! skip && (warn_level & 1))
+ || (skip && (warn_level & 8))))
+ cwarn( not_portable, op_name, 0L, skip ? non_eval : 0);
+ if (op == OP_DIV)
+ v1 /= v2;
+ else
+ v1 %= v2;
+ break;
+ case OP_ADD:
+ val = v1 + v2;
+ chk = (v2 > 0L && v1 > val) || (v2 < 0L && v1 < val);
+ if (chk
+#if HAVE_LONG_LONG
+ || (! stdc3
+ && (((long)v2 > 0L && (long)v1 > (long)val)
+ || ((long)v2 < 0L && (long)v1 < (long)val)))
+#endif
+ )
+ overflow( op_name, valpp, chk);
+ v1 = val;
+ break;
+ case OP_SUB:
+ val = v1 - v2;
+ chk = (v2 > 0L && val > v1) || (v2 < 0L && val < v1);
+ if (chk
+#if HAVE_LONG_LONG
+ || (! stdc3
+ && (((long)v2 > 0L && (long)val > (long)v1)
+ || ((long)v2 < 0L && (long)val < (long)v1)))
+#endif
+ )
+ overflow( op_name, valpp, chk);
+ v1 = val;
+ break;
+ case OP_SL: v1 <<= v2; break;
+ case OP_SR:
+ if (v1 < 0L
+ && ((!skip && (warn_level & 1))
+ || (skip && (warn_level & 8))))
+ cwarn( not_portable, op_name, 0L, skip ? non_eval : 0);
+ v1 >>= v2;
+ break;
+ case OP_LT: v1 = (v1 < v2); break;
+ case OP_LE: v1 = (v1 <= v2); break;
+ case OP_GT: v1 = (v1 > v2); break;
+ case OP_GE: v1 = (v1 >= v2); break;
+ case OP_EQ: v1 = (v1 == v2); break;
+ case OP_NE: v1 = (v1 != v2); break;
+ case OP_AND: v1 &= v2; break;
+ case OP_XOR: v1 ^= v2; break;
+ case OP_OR: v1 |= v2; break;
+ case OP_ANA: v1 = (v1 && v2); break;
+ case OP_ORO: v1 = (v1 || v2); break;
+ case OP_COL:
+ /*
+ * If v1 has the "true" value, v2 has the "false" value.
+ * The top of the value stack has the test.
+ */
+ v1 = (--*valpp)->val ? v1 : v2;
+ break;
+ default:
+ cfatal( illeg_op, op_name, 0L, 0);
+ }
+
+ *valpp = valp;
+ return v1;
+}
+
+static expr_t eval_unsigned(
+ VAL_SIGN ** valpp,
+ uexpr_t v1u,
+ uexpr_t v2u,
+ int op
+)
+/*
+ * Apply the argument operator to the unsigned data.
+ * Called from eval_eval() only in Standard mode.
+ */
+{
+ const char * const illeg_op
+ = "Bug: Illegal operator \"%s\" in eval_unsigned()"; /* _F_ */
+ const char * op_name = opname[ op];
+ VAL_SIGN * valp = *valpp;
+ uexpr_t v1 = 0;
+ int chk; /* Flag of overflow in unsigned long long */
+ int minus; /* Big integer converted from signed long */
+
+ minus = ! stdc3 && (v1u > ULONGMAX || v2u > ULONGMAX);
+
+ switch (op) {
+ case OP_EOE:
+ case OP_PLU: v1 = v1u; break;
+ case OP_NEG:
+ v1 = -v1u;
+ if (v1u)
+ overflow( op_name, valpp, TRUE);
+ break;
+ case OP_COM: v1 = ~v1u; break;
+ case OP_NOT: v1 = !v1u; break;
+ case OP_MUL:
+ v1 = v1u * v2u;
+ chk = v1u && v2u && (v1 / v2u != v1u || v1 / v1u != v2u);
+ if (chk
+#if HAVE_LONG_LONG
+ || (! stdc3 && ! minus && v1 > ULONGMAX)
+#endif
+ )
+ overflow( op_name, valpp, chk);
+ break;
+ case OP_DIV:
+ /* Division by 0 has been already diagnosed by eval_eval(). */
+ v1 = v1u / v2u;
+ break;
+ case OP_MOD:
+ v1 = v1u % v2u;
+ break;
+ case OP_ADD:
+ v1 = v1u + v2u;
+ chk = v1 < v1u;
+ if (chk
+#if HAVE_LONG_LONG
+ || (! stdc3 && ! minus && v1 > ULONGMAX)
+#endif
+ )
+ overflow( op_name, valpp, chk);
+ break;
+ case OP_SUB:
+ v1 = v1u - v2u;
+ chk = v1 > v1u;
+ if (chk
+#if HAVE_LONG_LONG
+ || (! stdc3 && ! minus && v1 > ULONGMAX)
+#endif
+ )
+ overflow( op_name, valpp, chk);
+ break;
+ case OP_SL: v1 = v1u << v2u; break;
+ case OP_SR: v1 = v1u >> v2u; break;
+ case OP_LT: v1 = (v1u < v2u); break;
+ case OP_LE: v1 = (v1u <= v2u); break;
+ case OP_GT: v1 = (v1u > v2u); break;
+ case OP_GE: v1 = (v1u >= v2u); break;
+ case OP_EQ: v1 = (v1u == v2u); break;
+ case OP_NE: v1 = (v1u != v2u); break;
+ case OP_AND: v1 = v1u & v2u; break;
+ case OP_XOR: v1 = v1u ^ v2u; break;
+ case OP_OR: v1 = v1u | v2u; break;
+ case OP_ANA: v1 = (v1u && v2u); break;
+ case OP_ORO: v1 = (v1u || v2u); break;
+ case OP_COL: valp--;
+ if (valp->val)
+ v1 = v1u;
+ else
+ v1 = v2u;
+ break;
+ default:
+ cfatal( illeg_op, op_name, 0L, 0);
+ }
+
+ *valpp = valp;
+ return v1;
+}
+
+static void overflow(
+ const char * op_name,
+ VAL_SIGN ** valpp,
+ int ll_overflow /* Flag of overflow in long long */
+)
+{
+ const char * const out_of_range
+ = "Result of \"%s\" is out of range%.0ld%s"; /* _E_ _W1_ _W8_ */
+
+#if HAVE_LONG_LONG
+ if (standard && ! ll_overflow) {
+ /* Overflow of long not in C99 mode */
+ if ((! skip && (warn_level & w_level)) || (skip && (warn_level & 8)))
+ cwarn( out_of_range, op_name, 0L, " of (unsigned) long");
+ } else
+#endif
+ if (skip) {
+ if (warn_level & 8)
+ cwarn( out_of_range, op_name, 0L, non_eval);
+ /* Else don't warn */
+ } else if (standard && (*valpp)->sign == UNSIGNED) {/* Never overflow */
+ if (warn_level & 1)
+ cwarn( out_of_range, op_name, 0L, 0);
+ } else {
+ cerror( out_of_range, op_name, 0L, 0);
+ (*valpp)->sign = VAL_ERROR;
+ }
+}
+
+static void dump_val(
+ const char * msg,
+ const VAL_SIGN * valp
+)
+/*
+ * Dump a value by internal representation.
+ */
+{
+#if HAVE_LONG_LONG
+ const char * const format
+ = "%s(%ssigned long long) 0x%016" LL_FORM "x";
+#else
+ const char * const format = "%s(%ssigned long) 0x%08lx";
+#endif
+ int sign = valp->sign;
+
+ mcpp_fprintf( DBG, format, msg, sign ? "" : "un", valp->val);
+}
+
+static void dump_stack(
+ const OPTAB * opstack, /* Operator stack */
+ const OPTAB * opp, /* Pointer into operator stack */
+ const VAL_SIGN * value, /* Value stack */
+ const VAL_SIGN * valp /* -> value vector */
+)
+/*
+ * Dump stacked operators and values.
+ */
+{
+ if (opstack < opp)
+ mcpp_fprintf( DBG, "Index op prec skip name -- op stack at %s"
+ , infile->bptr);
+
+ while (opstack < opp) {
+ mcpp_fprintf( DBG, " [%2d] %2d %04o %d %s\n", (int)(opp - opstack)
+ , opp->op, opp->prec, opp->skip, opname[ static_cast<size_t> (opp->op)]);
+ opp--;
+ }
+
+ while (value <= --valp) {
+ mcpp_fprintf( DBG, "value[%d].val = ", (int)(valp - value));
+ dump_val( "", valp);
+ mcpp_fputc( '\n', DBG);
+ }
+}
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/expand.cpp b/TAO/TAO_IDL/contrib/mcpp/expand.cpp
new file mode 100644
index 00000000000..209dba2232c
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/expand.cpp
@@ -0,0 +1,1584 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * E X P A N D . C
+ * M a c r o E x p a n s i o n
+ *
+ * The macro expansion routines are placed here.
+ */
+
+#if PREPROCESSED
+#include "mcpp.H"
+#else
+#include "system.H"
+#include "internal.H"
+#endif
+
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_stdio.h"
+
+#define ARG_ERROR (-255)
+#define CERROR 1
+#define CWARN 2
+
+static char * expand_std( DEFBUF * defp, char * out, char * out_end);
+ /* Expand a macro completely (for Standard modes) */
+static char * expand_prestd( DEFBUF * defp, char * out, char * out_end);
+ /* Expand a macro completely (for pre-Standard modes) */
+static DEFBUF * is_macro_call( DEFBUF * defp, char ** cp);
+ /* Is this really a macro call ? */
+static int collect_args( const DEFBUF * defp, char ** arglist);
+ /* Collect arguments of a macro call*/
+static int get_an_arg( int c, char ** argpp, char * arg_end
+ , char ** seqp, int var_arg);
+ /* Get an argument */
+static int squeeze_ws( char ** out);
+ /* Squeeze white spaces to a space */
+static void skip_macro( void);
+ /* Skip the rest of macro call */
+static void diag_macro( int severity, const char * format
+ , const char * arg1, long arg2, const char * arg3, const DEFBUF * defp1
+ , const DEFBUF * defp2) ;
+ /* Supplement diagnostic information*/
+static void dump_args( const char * why, int nargs, char ** arglist);
+ /* Dump arguments list */
+
+static int rescan_level; /* Times of macro rescan */
+static const char * const macbuf_overflow
+ = "Buffer overflow expanding macro \"%s\" at %.0ld\"%s\""; /* _E_ */
+static const char * const empty_arg
+ = "Empty argument in macro call \"%s\""; /* _W2_ */
+static const char * const unterm_macro
+ = "Unterminated macro call \"%s\""; /* _E_ */
+static const char * const narg_error
+ = "%s than necessary %ld argument(s) in macro call \"%s\""; /* _E_ _W1_ */
+static const char * const only_name
+ = "Macro \"%s\" needs arguments"; /* _W8_ */
+
+void expand_init( void)
+/* Set expand_macro() function */
+{
+ expand_macro = standard ? expand_std : expand_prestd;
+}
+
+DEFBUF * is_macro(
+ char ** cp
+)
+/*
+ * The name is already in 'identifier', the next token is not yet read.
+ * Return TRUE if the name is a macro call, else return FALSE.
+ */
+{
+ DEFBUF * defp;
+
+ if ((defp = look_id( identifier)) != 0) /* Is a macro name */
+ return is_macro_call( defp, cp);
+ else
+ return 0;
+}
+
+static DEFBUF * is_macro_call(
+ DEFBUF * defp,
+ char ** cp
+)
+/*
+ * Return TRUE if the defp->name is a macro call, else return FALSE.
+ */
+{
+ int c;
+
+ if (defp->nargs >= 0 /* Function-like macro */
+ || defp->nargs == DEF_PRAGMA) { /* _Pragma() pseudo-macro */
+ c = squeeze_ws( cp); /* See the next char. */
+ if (c == CHAR_EOF) { /* End of file */
+ unget_string( "\n", 0); /* Restore skipped '\n' */
+ } else if (! standard || c != RT_END) {
+ /* Still in the file and rescan boundary ? */
+ unget_ch(); /* To see it again */
+ }
+ if (c != '(') { /* Only the name of function-like macro */
+ if (! standard && warn_level & 8)
+ cwarn( only_name, defp->name, 0L, 0);
+ return 0;
+ }
+ }
+ return defp; /* Really a macro call */
+}
+
+/*
+ * expand_macro() expands a macro call completely, and writes out the result
+ * to the specified output buffer and returns the advanced pointer.
+ */
+
+
+/*
+ * T h e S T A N D A R D C o n f o r m i n g M o d e
+ * o f M a c r o E x p a n s i o n
+ *
+ * 1998/08 First released. kmatsui
+ */
+
+/* Return value of is_able_repl() */
+#define NO 0 /* "Blue-painted" */
+#define YES 1 /* Not blue-painted */
+#define READ_OVER 2
+ /* Still "blue-painted", yet has read over repl-list */
+
+static struct {
+ const DEFBUF * def; /* Macro definition */
+ int read_over; /* Has read over repl-list */
+ /* 'read_over' is never used in POST_STD mode and in compat_mode*/
+} replacing[ RESCAN_LIMIT]; /* Macros currently replacing */
+
+static char * replace( DEFBUF * defp, char * out, char * out_end
+ , const DEFBUF * outer, FILEINFO * rt_file);
+ /* Replace a macro recursively */
+static DEFBUF * def_special( DEFBUF * defp);
+ /* Re-define __LINE__, __FILE__ */
+static int prescan( const DEFBUF * defp, char ** arglist, char * out
+ , char * out_end);
+ /* Process #, ## operator */
+static char * catenate( const DEFBUF * defp, char ** arglist, char * out
+ , char * out_end, char ** token_p);
+ /* Catenate tokens */
+static char * stringize( const DEFBUF * defp, char * argp, char * out);
+ /* Stringize an argument */
+static char * substitute( const DEFBUF * defp, int gvar_arg, char ** arglist
+ , const char * in, char * out, char * out_end);
+ /* Substitute parms with arguments */
+static char * rescan( const DEFBUF * outer, const char * in, char * out
+ , char * out_end);
+ /* Rescan once replaced sequences */
+static int disable_repl( const DEFBUF * defp);
+ /* Disable the macro once replaced */
+static void enable_repl( const DEFBUF * defp, int done);
+ /* Enable the macro for later use */
+static int is_able_repl( const DEFBUF * defp);
+ /* Is the macro allowed to replace? */
+
+static char * expand_std(
+ DEFBUF * defp, /* Macro definition */
+ char * out, /* Output buffer */
+ char * out_end /* End of output buffer */
+)
+/*
+ * Expand a macro call completely, write the results to the specified buffer
+ * and return the advanced pointer.
+ */
+{
+ char macrobuf[ NMACWORK + IDMAX]; /* Buffer for replace() */
+ char * out_p = out;
+ size_t len;
+ int c, c1;
+ char * cp;
+
+ macro_line = src_line; /* Line number for diag */
+ macro_name = defp->name;
+ rescan_level = 0;
+ if (replace( defp, macrobuf, macrobuf + NMACWORK, 0
+ , infile) == 0) { /* Illegal macro call */
+ skip_macro();
+ macro_line = MACRO_ERROR;
+ goto exp_end;
+ }
+ len = (size_t) (out_end - out);
+ if (ACE_OS::strlen( macrobuf) > len) {
+ cerror( macbuf_overflow, macro_name, 0, macrobuf);
+ ACE_OS::memcpy( out, macrobuf, len);
+ out_p = out + len;
+ macro_line = MACRO_ERROR;
+ goto exp_end;
+ }
+
+ cp = macrobuf;
+ c1 = '\0';
+ while ((c = *cp++) != EOS) {
+ if (c == DEF_MAGIC)
+ continue; /* Skip DEF_MAGIC */
+ if (mcpp_mode == STD) {
+ if (c == IN_SRC)
+ continue; /* Skip IN_SRC */
+ else if (c == TOK_SEP) {
+ if (c1 == ' ' || in_include || lang_asm)
+ continue;
+ /* Skip separator just after ' ' and in #include line */
+ /* Also skip this in lang_asm mode */
+ else
+ c = ' ';
+ }
+ }
+ c1 = c;
+ *out_p++ = c;
+ }
+
+ macro_line = 0;
+exp_end:
+ *out_p = EOS;
+ if (mcpp_debug & EXPAND)
+ dump_string( "expand_std exit", out);
+ macro_name = 0;
+ clear_exp_mac(); /* Clear the information for diagnostic */
+ return out_p;
+}
+
+static char * replace(
+ DEFBUF * defp, /* Macro to be replaced */
+ char * out, /* Output Buffer */
+ char * out_end, /* End of output buffer */
+ const DEFBUF * outer, /* Outer macro replacing*/
+ FILEINFO * rt_file /* Repl-text "file" */
+)
+/*
+ * Replace a possibly nested macro recursively.
+ * replace() and rescan() call each other recursively.
+ * Return the advanced output pointer or 0 on error.
+ */
+{
+ char ** arglist = 0; /* Pointers to arguments*/
+ int nargs; /* Number of arguments expected */
+ char * catbuf; /* Buffer for prescan() */
+ char * expbuf; /* Buffer for substitute() */
+ char * out_p; /* Output pointer */
+
+ if (mcpp_debug & EXPAND) {
+ dump_a_def( "replace entry", defp, FALSE, FALSE, TRUE, fp_debug);
+ dump_unget( "replace entry");
+ }
+ nargs = (defp->nargs == DEF_PRAGMA) ? 1 : (defp->nargs & ~AVA_ARGS);
+
+ if (nargs < DEF_NOARGS - 2) { /* __FILE__, __LINE__ */
+ defp = def_special( defp);
+ if (mcpp_mode == STD) {
+ *out++ = TOK_SEP; /* Wrap repl-text with token */
+ out = stpcpy( out, defp->repl); /* separators to pre- */
+ *out++ = TOK_SEP; /* vent token merging.*/
+ *out = EOS;
+ } else {
+ out = stpcpy( out, defp->repl);
+ }
+ return out;
+ } else if (nargs >= 0) { /* Function-like macro */
+ squeeze_ws( 0); /* Skip to '(' */
+ arglist = (char **) xmalloc( (nargs + 1) * sizeof (char *));
+ arglist[ 0] = xmalloc( (size_t) (NMACWORK + IDMAX * 2));
+ /* Note: arglist[ n] may be reallocated */
+ /* and re-written by collect_args() */
+ if (collect_args( defp, arglist) == ARG_ERROR) {
+ ACE_OS::free( arglist[ 0]); /* Syntax error */
+ ACE_OS::free( arglist);
+ return 0;
+ }
+ if (mcpp_mode == STD && outer && rt_file != infile) {
+ /* Has read over replacement-text */
+ if (compat_mode) {
+ enable_repl( outer, FALSE); /* Enable re-expansion */
+ if (mcpp_debug & EXPAND)
+ dump_string( "enabled re-expansion"
+ , outer ? outer->name : "<arg>");
+ } else {
+ replacing[ rescan_level-1].read_over = READ_OVER;
+ }
+ }
+ }
+
+ catbuf = xmalloc( (size_t) (NMACWORK + IDMAX));
+ if (mcpp_debug & EXPAND) {
+ mcpp_fprintf( DBG, "(%s)", defp->name);
+ dump_string( "prescan entry", defp->repl);
+ }
+ if (prescan( defp, arglist, catbuf, catbuf + NMACWORK) == FALSE) {
+ /* Process #, ## operators */
+ diag_macro( CERROR, macbuf_overflow, defp->name, 0L, catbuf, defp
+ , 0);
+ if (nargs >= 0) {
+ ACE_OS::free( arglist[ 0]);
+ ACE_OS::free( arglist);
+ }
+ ACE_OS::free( catbuf);
+ return 0;
+ }
+ catbuf = xrealloc( catbuf, ACE_OS::strlen( catbuf) + 1);
+ /* Use memory sparingly */
+ if (mcpp_debug & EXPAND) {
+ mcpp_fprintf( DBG, "(%s)", defp->name);
+ dump_string( "prescan exit", catbuf);
+ }
+
+ if (nargs > 0) { /* Function-like macro with any argument */
+ int gvar_arg;
+ expbuf = xmalloc( (size_t) (NMACWORK + IDMAX));
+ if (mcpp_debug & EXPAND) {
+ mcpp_fprintf( DBG, "(%s)", defp->name);
+ dump_string( "substitute entry", catbuf);
+ }
+ gvar_arg = (defp->nargs & GVA_ARGS) ? (defp->nargs & ~AVA_ARGS) : 0;
+ out_p = substitute( defp, gvar_arg, arglist, catbuf, expbuf
+ , expbuf + NMACWORK); /* Expand each arguments*/
+ ACE_OS::free( arglist[ 0]);
+ ACE_OS::free( arglist);
+ ACE_OS::free( catbuf);
+ expbuf = xrealloc( expbuf, ACE_OS::strlen( expbuf) + 1);
+ /* Use memory sparingly */
+ if (mcpp_debug & EXPAND) {
+ mcpp_fprintf( DBG, "(%s)", defp->name);
+ dump_string( "substitute exit", expbuf);
+ }
+ } else { /* Object-like macro or */
+ if (nargs == 0) { /* Function-like macro with no argument */
+ ACE_OS::free( arglist[ 0]);
+ ACE_OS::free( arglist);
+ }
+ out_p = expbuf = catbuf;
+ }
+
+ if (out_p)
+ out_p = rescan( defp, expbuf, out, out_end);
+ if (out_p && defp->nargs == DEF_PRAGMA)
+ has_pragma = TRUE;
+ /* Inform mcpp_main() that _Pragma() was found */
+ ACE_OS::free( expbuf);
+ return out_p;
+}
+
+static DEFBUF * def_special(
+ DEFBUF * defp /* Macro definition */
+)
+/*
+ * Re-define __LINE__, __FILE__.
+ * Return the new definition.
+ */
+{
+ const FILEINFO * file;
+ DEFBUF ** prevp;
+ int cmp;
+
+ switch (defp->nargs) {
+ case DEF_NOARGS - 3: /* __LINE__ */
+ if ((src_line > line_limit || src_line <= 0) && (warn_level & 1))
+ diag_macro( CWARN
+ , "Line number %.0s\"%ld\" is out of range" /* _W1_ */
+ , 0, src_line, 0, defp, 0);
+ ACE_OS::sprintf( defp->repl, "%ld", src_line); /* Re-define */
+ break;
+ case DEF_NOARGS - 4: /* __FILE__ */
+ for (file = infile; file != 0; file = file->parent) {
+ if (file->fp != 0) {
+ ACE_OS::sprintf( work_buf, "\"%s%s\"", *(file->dirp), file->filename);
+ if (str_eq( work_buf, defp->repl))
+ break; /* No change */
+ defp->nargs = DEF_NOARGS; /* Enable to redefine */
+ prevp = look_prev( defp->name, &cmp);
+ defp = install_macro( "__FILE__", DEF_NOARGS - 4, "", work_buf
+ , prevp, cmp); /* Re-define */
+ break;
+ }
+ }
+ break;
+ }
+ return defp;
+}
+
+static int prescan(
+ const DEFBUF * defp, /* Definition of the macro */
+ char ** arglist, /* Pointers to actual arguments */
+ char * out, /* Output buffer */
+ char * out_end /* End of output buffer */
+)
+/*
+ * Concatenate the tokens surounding ## by catenate(), and stringize the
+ * argument following # by stringize().
+ */
+{
+ FILEINFO * file;
+ char * prev_token = 0; /* Preceding token */
+ int c; /* Value of a character */
+ /*
+ * The replacement lists are --
+ * stuff1<SEP>stuff2
+ * or stuff1<SEP>stuff2<SEP>stuff3...
+ * where <SEP> is CAT, maybe with preceding space and following space,
+ * stuff might be
+ * ordinary-token
+ * MAC_PARM<n>
+ * or <QUO>MAC_PARM<n>
+ * where <QUO> is ST_QUO, possibly with following space.
+ */
+
+ if (mcpp_mode == POST_STD) {
+ file = unget_string( defp->repl, defp->name);
+ } else {
+ *out++ = TOK_SEP; /* Wrap replacement */
+ workp = work_buf; /* text with token */
+ workp = stpcpy( workp, defp->repl); /* separators to */
+ *workp++ = TOK_SEP; /* prevent unintended*/
+ *workp = EOS; /* token merging. */
+ file = unget_string( work_buf, defp->name);
+ }
+
+ while (c = get_ch(), file == infile) { /* To the end of repl */
+
+ switch (c) {
+ case ST_QUOTE:
+ skip_ws(); /* Skip space, MAC_PARM */
+ c = get_ch() - 1; /* Parameter number */
+ prev_token = out; /* Remember the token */
+ out = stringize( defp, arglist[ c], out);
+ /* Stringize without expansion */
+ break;
+ case CAT:
+ if (*prev_token == DEF_MAGIC || *prev_token == IN_SRC) {
+ ACE_OS::memmove( prev_token, prev_token + 1, ACE_OS::strlen( prev_token + 1));
+ *--out = EOS; /* Remove DEF_MAGIC, IN_SRC */
+ }
+#if COMPILER == GNUC
+ if (*prev_token == ',')
+ break; /* ', ##' sequence (peculiar to GCC) */
+#endif
+ out = catenate( defp, arglist, out, out_end, &prev_token);
+ break;
+ case MAC_PARM:
+ prev_token = out;
+ *out++ = MAC_PARM;
+ *out++ = get_ch(); /* Parameter number */
+ break;
+ case TOK_SEP:
+ /* Fall through */
+ case ' ':
+ *out++ = c;
+ break;
+ default:
+ prev_token = out;
+ scan_token( c, &out, out_end); /* Ordinary token */
+ break;
+ }
+
+ *out = EOS; /* Ensure termination */
+ if (out_end <= out) /* Buffer overflow */
+ return FALSE;
+ }
+
+ *out = EOS; /* Ensure terminatation in case of no token */
+ unget_ch();
+ return TRUE;
+}
+
+static char * catenate(
+ const DEFBUF * defp, /* The macro definition */
+ char ** arglist, /* Pointers to actual arguments */
+ char * out, /* Output buffer */
+ char * out_end, /* End of output buffer */
+ char ** token_p /* Address of preceding token pointer */
+)
+/*
+ * Concatenate the previous and the following tokens.
+ * Note: The parameter codes may coincide with white spaces or any
+ * other characters.
+ */
+{
+ FILEINFO * file;
+ char * prev_prev_token = 0;
+ const char * invalid_token
+ = "Not a valid preprocessing token \"%s\""; /* _E_ _W2_ */
+ const char * argp; /* Pointer to an actual argument*/
+ char * prev_token = *token_p; /* Preceding token */
+ int in_arg = FALSE;
+ int c; /* Value of a character */
+
+ while ((*(out - 1) == ' ' || *(out - 1) == TOK_SEP)
+ && (*(out - 2) != MAC_PARM || prev_token != out - 2))
+ out--; /* Remove spaces and inserted separators */
+ *out = EOS;
+
+ /* Get the previous token */
+ if (*prev_token == MAC_PARM) { /* Formal parameter */
+ c = (*(prev_token + 1) & UCHARMAX) - 1; /* Parm number */
+ argp = arglist[ c]; /* Actual argument */
+ out = prev_token; /* To overwrite */
+ if ((mcpp_mode == POST_STD && *argp == EOS)
+ || (mcpp_mode == STD && *argp == RT_END)) {
+ *out = EOS; /* An empty argument */
+ } else {
+ if (mcpp_mode == POST_STD) {
+ file = unget_string( argp, 0);
+ while (c = get_ch(), file == infile) {
+ prev_token = out; /* Remember the last token */
+ scan_token( c, &out, out_end);
+ } /* Copy actual argument without expansion */
+ unget_ch();
+ } else {
+ unget_string( argp, 0);
+ while ((c = get_ch()) != RT_END) {
+ prev_prev_token = prev_token;
+ prev_token = out; /* Remember the last token */
+ scan_token( c, &out, out_end);
+ } /* Copy actual argument without expansion */
+ if (*prev_token == TOK_SEP) {
+ out = prev_token;
+ prev_token = prev_prev_token; /* Skip separator */
+ }
+ }
+ if (*prev_token == DEF_MAGIC
+ || (mcpp_mode == STD && *prev_token == IN_SRC)) {
+ ACE_OS::memmove( prev_token, prev_token + 1
+ , (size_t) (out-- - prev_token));
+ /* Remove DEF_MAGIC enabling the name to replace later */
+ }
+ }
+ }
+ c = skip_ws();
+
+ /* Catenate */
+ switch (c) {
+ case ST_QUOTE: /* First stringize and then catenate */
+ skip_ws(); /* Skip MAC_PARM, ST_QUOTE */
+ c = get_ch() - 1;
+ out = stringize( defp, arglist[ c], out);
+ break;
+ case MAC_PARM:
+ c = get_ch() - 1; /* Parameter number */
+ argp = arglist[ c]; /* Actual argument */
+ if ((mcpp_mode == POST_STD && *argp == EOS)
+ || (mcpp_mode == STD && *argp == RT_END))
+ *out = EOS; /* An empty argument */
+ else {
+ unget_string( argp, 0);
+ if ((c = get_ch()) == DEF_MAGIC) /* Remove DEF_MAGIC */
+ c = get_ch(); /* enabling to replace */
+ else if (c == IN_SRC) /* Remove IN_SRC */
+ c = get_ch();
+ scan_token( c, &out, out_end); /* The first token */
+ if (*infile->bptr) /* There are more tokens*/
+ in_arg = TRUE;
+ }
+ break;
+ case DEF_MAGIC:
+ case IN_SRC:
+ c = get_ch(); /* Skip DEF_MAGIC, IN_SRC */
+ /* Fall through */
+ default:
+ scan_token( c, &out, out_end); /* Copy the token */
+ break;
+ }
+
+ /* The generated sequence is a valid preprocessing-token ? */
+ if (*prev_token) { /* There is any token */
+ unget_string( prev_token, 0); /* Scan once more */
+ c = get_ch(); /* This line should be before the next line. */
+ infile->fp = (FILE *)-1; /* To check token length*/
+ if (mcpp_debug & EXPAND)
+ dump_string( "checking generated token", infile->buffer);
+ scan_token( c, (workp = work_buf, &workp), work_end);
+ infile->fp = 0;
+ if (*infile->bptr != EOS) { /* More than a token */
+ if (lang_asm) { /* Assembler source */
+ if (warn_level & 2)
+ diag_macro( CWARN, invalid_token, prev_token, 0L, 0
+ , defp, 0);
+ } else {
+ diag_macro( CERROR, invalid_token, prev_token, 0L, 0, defp
+ , 0);
+ }
+ infile->bptr += ACE_OS::strlen( infile->bptr);
+ }
+ get_ch(); /* To the parent "file" */
+ unget_ch();
+ }
+
+ if (mcpp_mode == STD && ! lang_asm) {
+ *out++ = TOK_SEP; /* Prevent token merging*/
+ *out = EOS;
+ }
+ if (in_arg) {
+ if (mcpp_mode == POST_STD) {
+ file = infile;
+ while (c = get_ch(), file == infile) {
+ prev_token = out; /* Remember the last token */
+ scan_token( c, &out, out_end);
+ } /* Copy rest of argument without expansion */
+ unget_ch();
+ } else {
+ while ((c = get_ch()) != RT_END) {
+ prev_token = out; /* Remember the last token */
+ scan_token( c, &out, out_end);
+ } /* Copy rest of argument without expansion */
+ }
+ }
+ *token_p = prev_token; /* Report back the generated token */
+
+ return out;
+}
+
+static char * stringize(
+ const DEFBUF * defp, /* The macro definition */
+ char * argp, /* Pointer to argument */
+ char * out /* Output buffer */
+)
+/*
+ * Make a string literal from an argument.
+ */
+{
+ FILEINFO * file;
+ int stray_bsl = FALSE; /* '\\' not in literal */
+ char * out_p = out;
+ int token_type;
+ int c;
+
+ *out_p++ = '"';
+
+ file = unget_string( argp, 0);
+
+ while ((c = get_ch()), ((mcpp_mode == POST_STD && file == infile)
+ || (mcpp_mode == STD && c != RT_END))) {
+ if (c == ' ') {
+ *out_p++ = ' ';
+ continue;
+ }
+ if (mcpp_mode == STD && (c == TOK_SEP || c == IN_SRC))
+ continue; /* Skip inserted separator and in-src magic */
+ if (c == '\\')
+ stray_bsl = TRUE; /* May cause a trouble */
+ token_type = scan_token( c, (workp = work_buf, &workp), work_end);
+
+ switch (token_type) {
+ case WSTR:
+ case WCHR:
+ case STR:
+ case CHR:
+ workp = work_buf;
+ while ((c = *workp++ & UCHARMAX) != EOS) {
+ if (char_type[ c] & mbstart) { /* Multi-byte character */
+ mb_read( c, &workp, (*out_p++ = c, &out_p));
+ /* Copy as it is */
+ continue;
+ }
+ if (c == '"') {
+ *out_p++ = '\\'; /* Insert '\\' */
+ } else if (c == '\\') {
+#if OK_UCN
+ if (mcpp_mode == POST_STD || ! stdc3
+ || (*workp != 'u' && *workp != 'U'))
+ /* Not UCN */
+#endif
+ *out_p++ = '\\';
+ }
+ *out_p++ = c;
+ }
+ *out_p = EOS;
+ break;
+ default:
+ out_p = stpcpy( out_p, work_buf);
+ break;
+ }
+ }
+
+ if (mcpp_mode == POST_STD)
+ unget_ch();
+ *out_p++ = '"';
+ *out_p = EOS;
+
+ if (stray_bsl) {
+ int invalid = FALSE;
+ unget_string( out, defp->name);
+ if (mcpp_debug & EXPAND)
+ dump_string( "checking generated token", infile->buffer);
+ scan_quote( get_ch(), work_buf, work_end, TRUE);
+ /* Unterminated or too long string will be diagnosed */
+ if (*infile->bptr != EOS) /* More than a token */
+ invalid = TRUE; /* Diagnose after clearing the "file" */
+ infile->bptr += ACE_OS::strlen( infile->bptr);
+ get_ch(); /* Clear the "file" */
+ unget_ch();
+ if (invalid)
+ diag_macro( CERROR
+ , "Not a valid string literal %s" /* _E_ */
+ , out, 0L, 0, defp, 0);
+ }
+#if NWORK-2 > SLEN90MIN
+ else if ((warn_level & 4) && out_p - out > str_len_min)
+ diag_macro( CWARN
+ , "String literal longer than %.0s%ld bytes %s" /* _W4_ */
+ , 0 , (long) str_len_min, out, defp, 0);
+#endif
+ return out_p;
+}
+
+static char * substitute(
+ const DEFBUF * , /* The macro getting arguments */
+ int , /* gvar_arg's argument is GCC3 variable argument*/
+ char ** arglist, /* Pointers to actual arguments */
+ const char * in, /* Replacement text */
+ char * out, /* Output buffer */
+ char * out_end /* End of output buffer */
+)
+/*
+ * Replace completely each actual arguments of the macro, and substitute for
+ * the formal parameters in the replacement list.
+ */
+{
+ //char * out_start = out;
+ int c;
+
+ *out = EOS; /* Ensure to termanate */
+ while ((c = *in++) != EOS) {
+ if (c == MAC_PARM) { /* Formal parameter */
+ c = *in++ & UCHARMAX; /* Parameter number */
+ if (mcpp_debug & EXPAND) {
+ mcpp_fprintf( DBG, " (expanding arg[%d])", c);
+ dump_string( 0, arglist[ c - 1]);
+ }
+#if COMPILER == GNUC
+ if (c == gvar_arg && *(arglist[ c - 1]) == RT_END) {
+ /* GCC3 variadic macro and its variable argument is absent */
+ char * tmp;
+ tmp = out - 1;
+ while (*tmp == ' ')
+ tmp--;
+ if (*tmp == ',') {
+ out = tmp; /* Remove the immediately preceding ',' */
+ if (warn_level & 1) {
+ *out = EOS;
+ diag_macro( CWARN,
+ "Removed ',' preceding the absent variable argument: %s" /* _W1_ */
+ , out_start, 0L, 0, defp, 0);
+ }
+ }
+ } else
+#endif
+ if ((out = rescan( 0, arglist[ c - 1], out, out_end))
+ == 0) { /* Replace completely */
+ return 0; /* Error */
+ }
+ } else {
+ *out++ = c; /* Copy the character */
+ }
+ }
+ *out = EOS;
+ return out;
+}
+
+static char * rescan(
+ const DEFBUF * outer, /* Outer macro just replacing */
+ const char * in, /* Sequences to be rescanned */
+ char * out, /* Output buffer */
+ char * out_end /* End of output buffer */
+)
+/*
+ * Re-scan the once replaced sequences to replace the remaining macros
+ * completely.
+ * rescan() and replace() call each other recursively.
+ *
+ * Note: POST_STD mode does not use IN_SRC nor TOK_SEP and seldom uses RT_END.
+ * Checking of those are unnecessary overhead for POST_STD mode. To integrate
+ * the code for POST_STD with STD mode, however, we use these checkings
+ * commonly.
+ * compat_mode also does not use IN_SRC.
+ */
+{
+ char * cur_cp = 0;
+ char * tp = 0; /* Temporary pointer into buffer*/
+ char * out_p = out; /* Current output pointer */
+ FILEINFO * file; /* Input sequences stacked on a "file" */
+ DEFBUF * inner = 0; /* Inner macro to replace */
+ int c; /* First character of token */
+
+ if (mcpp_debug & EXPAND) {
+ mcpp_fprintf( DBG, "rescan_level--%d (%s) "
+ , rescan_level + 1, outer ? outer->name : "<arg>");
+ dump_string( "rescan entry", in);
+ }
+ if (! disable_repl( outer)) /* Don't re-replace replacing macro */
+ return 0; /* Too deeply nested macro call */
+ if (mcpp_mode == STD) {
+ get_ch(); /* Clear empty "file"s */
+ unget_ch(); /* for diagnostic */
+ cur_cp = infile->bptr; /* Remember current location */
+ }
+ file = unget_string( in, outer ? outer->name : 0);
+ /* Stack input on a "file" */
+
+ while ((c = get_ch()), file == infile
+ /* Rescanning is limited to the "file" */
+ && c != RT_END) {
+ /*
+ * This is the trick of STD mode. collect_args() via replace()
+ * may read over to file->parent (provided the "file" is macro)
+ * unless stopped by RT_END.
+ */
+
+ if (c == ' ' || c == TOK_SEP) {
+ *out_p++ = c;
+ continue;
+ }
+ if (scan_token( c, (tp = out_p, &out_p), out_end) == NAM
+ && c != DEF_MAGIC && (inner =
+ look_id( (mcpp_mode == STD && c == IN_SRC) ? tp+1 : tp))
+ != 0) { /* A macro name */
+ int is_able; /* Macro is not "blue-painted" */
+ char * inp_save = infile->bptr; /* Remember current bptr*/
+
+ if (is_macro_call( inner, &out_p)
+ && ((mcpp_mode == POST_STD && is_able_repl( inner))
+ || (mcpp_mode == STD
+ && (((is_able = is_able_repl( inner)) == YES)
+ || (is_able == READ_OVER && c == IN_SRC))))) {
+ /* Really a macro call */
+ if ((out_p = replace( inner, tp, out_end, outer, file))
+ == 0) /* Error of macro call */
+ break;
+ } else {
+ if (file != infile && infile->bptr != inp_save
+ && *(infile->bptr - 1) == ' ') {
+ /* Has read over spaces into the parent "file" */
+ infile->bptr--; /* Pushback forcibly */
+ out_p--;
+ }
+ if ((is_able = is_able_repl( inner)) == NO
+ || (mcpp_mode == STD && is_able == READ_OVER
+ && c != IN_SRC)) {
+ if (mcpp_mode == POST_STD || c != IN_SRC)
+ ACE_OS::memmove( tp + 1, tp, (size_t) (out_p++ - tp));
+ *tp = DEF_MAGIC; /* Mark not to replace */
+ } /* Else not a macro call*/
+ }
+ }
+ if (out_end <= out_p) {
+ *out_p = EOS;
+ diag_macro( CERROR, macbuf_overflow, outer ? outer->name : in, 0L
+ , out, outer, inner);
+ out_p = 0;
+ break;
+ }
+ }
+
+ if (out_p) {
+ *out_p = EOS;
+ if (mcpp_mode == STD) {
+ if (c != RT_END) {
+ unget_ch();
+ if (outer != 0) { /* outer isn't a macro in argument */
+ if (infile && infile->bptr != cur_cp
+ /* Have overrun replacement list*/
+ && !(tp && *tp == DEF_MAGIC)
+ /* Macro is enabled */
+ && ((!compat_mode && (warn_level & 1))
+ || (compat_mode && (warn_level & 8)))) {
+ diag_macro( CWARN,
+"Replacement text \"%s\" of macro %.0ld\"%s\" involved subsequent text" /* _W1_ */
+ , in, 0L, outer->name, outer, inner);
+ }
+ }
+ } /* Else remove RT_END */
+ } else {
+ unget_ch();
+ }
+ }
+ enable_repl( outer, TRUE); /* Enable macro for later text */
+ if (mcpp_debug & EXPAND) {
+ mcpp_fprintf( DBG, "rescan_level--%d (%s) "
+ , rescan_level + 1, outer ? outer->name : "<arg>");
+ dump_string( "rescan exit", out);
+ }
+ return out_p;
+}
+
+static int
+disable_repl(
+ const DEFBUF * defp
+)
+/*
+ * Register the macro name currently replacing.
+ */
+{
+ if (defp == 0)
+ return TRUE;
+ if (rescan_level >= RESCAN_LIMIT) {
+ diag_macro( CERROR,
+ "Rescanning macro \"%s\" more than %ld times at \"%s\"" /* _E_ */
+ , macro_name, (long) RESCAN_LIMIT, defp->name, defp, 0);
+ return FALSE;
+ }
+ replacing[ rescan_level].def = defp;
+ replacing[ rescan_level++].read_over = NO;
+ return TRUE;
+}
+
+static void enable_repl(
+ const DEFBUF * defp,
+ int done
+)
+/*
+ * Un-register the macro name just replaced for later text.
+ */
+{
+ if (defp == 0)
+ return;
+ replacing[ rescan_level - 1].def = 0;
+ if (done && rescan_level)
+ rescan_level--;
+}
+
+static int is_able_repl(
+ const DEFBUF * defp
+)
+/*
+ * The macro is permitted to replace ?
+ */
+{
+ int i;
+
+ if (defp == 0)
+ return YES;
+ for (i = rescan_level-1; i >= 0; i--) {
+ if (defp == replacing[ i].def)
+ return replacing[ i].read_over;
+ }
+ return YES;
+}
+
+
+/*
+ * M a c r o E x p a n s i o n i n P R E - S T A N D A R D M o d e
+ */
+
+#include "setjmp.h"
+
+static jmp_buf jump;
+
+static char * arglist_pre[ NMACPARS]; /* Pointers to args */
+
+static int rescan_pre( int c, char * mp, char * mac_end);
+ /* Replace a macro repeatedly */
+static int replace_pre( DEFBUF * defp);
+ /* Replace a macro once */
+static void substitute_pre( DEFBUF * defp);
+ /* Substitute parms with args */
+
+static char * expand_prestd(
+ DEFBUF * defp, /* Macro definition */
+ char * out, /* Output buffer */
+ char * out_end /* End of output buffer */
+)
+/*
+ * Expand a macro call completely, write the results to the specified buffer
+ * and return the advanced pointer.
+ */
+{
+ char macrobuf[ NMACWORK + IDMAX]; /* Buffer for rescan_pre() */
+ char * mac_end = &macrobuf[ NMACWORK]; /* End of macrobuf[] */
+ char * out_p; /* Pointer into out[] */
+ char * mp = macrobuf; /* Pointer into macrobuf*/
+ int len; /* Length of a token */
+ int token_type; /* Type of token */
+ int c;
+
+ macro_line = src_line; /* Line number for diag.*/
+ unget_string( identifier, identifier); /* To re-read */
+ macro_name = defp->name;
+ rescan_level = 0;
+ if (setjmp( jump) == 1) {
+ skip_macro();
+ mp = macrobuf;
+ *mp = EOS;
+ macro_line = MACRO_ERROR;
+ goto err_end;
+ }
+
+ while ((c = get_ch()) != CHAR_EOF && infile->fp == 0) {
+ /* While the input stream is a macro */
+ while (c == ' ') { /* Output the spaces */
+ *mp++ = c;
+ c = get_ch();
+ if (infile == 0 || infile->fp != 0)
+ goto exp_end;
+ }
+ token_type = rescan_pre( c, mp, mac_end); /* Scan token */
+ /* and expand. Result of expansion is written at mp. */
+
+ switch (token_type) {
+ case STR: /* String literal */
+ case CHR: /* Character constant */
+ case NUM: /* Number token */
+ case OPE: /* Operator or punct. */
+ case NAM: /* Identifier */
+ len = ACE_OS::strlen( mp);
+ mp += len;
+ break;
+ case SEP: /* Special character */
+ switch( *mp) {
+ case COM_SEP:
+ if (mcpp_mode == OLD_PREP)
+ break; /* Zero-length comment is removed now */
+ /* Else fall through */
+ default: /* Who knows ? */
+ mp++; /* Copy the character */
+ break;
+ }
+ break;
+ case NO_TOKEN: break; /* End of file */
+ default: /* Unkown token char. */
+ mp++; /* Copy the character */
+ break;
+ }
+
+ if (mac_end <= mp) {
+ *mp = EOS;
+ cerror( macbuf_overflow, macro_name, 0L, macrobuf);
+ longjmp( jump, 1);
+ }
+ if (mcpp_debug & GETC) {
+ *mp = EOS;
+ dump_string( "macrobuf", macrobuf);
+ }
+ }
+
+exp_end:
+ unget_ch();
+ while (macrobuf < mp && *(mp - 1) == ' ')
+ mp--; /* Remove trailing blank */
+ macro_line = 0;
+ *mp = EOS;
+ if (mp - macrobuf > out_end - out) {
+ cerror( macbuf_overflow, macro_name, 0L, macrobuf);
+ macro_line = MACRO_ERROR;
+ }
+err_end:
+ out_p = stpcpy( out, macrobuf);
+ if (mcpp_debug & EXPAND) {
+ dump_string( "expand_prestd exit", out);
+ }
+ macro_name = 0;
+ clear_exp_mac();
+ return out_p;
+}
+
+static int rescan_pre(
+ int c, /* First character of token */
+ char * mp, /* Output buffer */
+ char * mac_end /* End of output buffer */
+)
+/*
+ * If the token is a macro name, replace the macro repeatedly until the first
+ * token becomes a non-macro and return the type of token after expansion.
+ */
+{
+ int token_type; /* Type of token */
+ char * cp = mp; /* Value of mp should not be changed */
+ DEFBUF * defp;
+ FILEINFO * file;
+
+ while ((token_type = scan_token( c, &cp, mac_end)) == NAM
+ && (defp = look_id( identifier)) != 0) { /* Macro */
+ if (replace_pre( defp) == FALSE)
+ break; /* Macro name with no argument */
+ file = infile;
+ c = get_ch();
+ if (file != infile) { /* Replaced to 0 token */
+ unget_ch();
+ token_type = NO_TOKEN;
+ break;
+ }
+ cp = mp; /* Overwrite on the macro call */
+ } /* The macro call is replaced */
+ return token_type;
+}
+
+static int replace_pre(
+ DEFBUF * defp /* Definition of the macro */
+)
+/*
+ * Replace a macro one level. Called from expand_prestd() (via rescan_pre())
+ * when an identifier is found in the symbol table. It calls collect_args()
+ * to parse actual arguments, checking for the correct number. It then
+ * creates a "file" containing single line containing the replacement text
+ * with the actual arguments inserted appropriately. This is "pushed back"
+ * onto the input stream. (When get_ch() routine runs off the end of the macro
+ * line, it will dismiss the macro itself.)
+ */
+{
+ int nargs; /* Number of arguments */
+ int c;
+
+ if (mcpp_debug & EXPAND) {
+ dump_a_def( "replace_pre entry", defp, FALSE, FALSE, TRUE, fp_debug);
+ dump_unget( "replace_pre entry");
+ }
+ if (++rescan_level >= PRESTD_RESCAN_LIMIT) {
+ diag_macro( CERROR
+ , "Recursive macro definition of \"%s\"" /* _E_ */
+ , defp->name, 0L, 0, defp, 0);
+ longjmp( jump, 1);
+ }
+
+ /*
+ * Here's a macro to replace.
+ */
+ switch (defp->nargs) {
+
+ case DEF_NOARGS: /* No argument just stuffs */
+ case DEF_NOARGS - 1: /* Non-standard predef */
+ break;
+
+ default: /* defp->nargs >= 0 */
+ /*
+ * Nothing funny about this macro.
+ */
+ c = squeeze_ws( 0); /* Look for and skip '('*/
+ if (c != '(') {
+ /*
+ * If the programmer writes
+ * #define foo() ...
+ * ...
+ * foo [no ()]
+ * just write foo to output.
+ */
+ unget_ch();
+ if (warn_level & 8)
+ diag_macro( CWARN, only_name, defp->name, 0L, 0, defp, 0);
+ return FALSE;
+ } else {
+ arglist_pre[ 0] = xmalloc( (size_t) (NMACWORK + IDMAX * 2));
+ nargs = collect_args( defp, arglist_pre);
+ /* Collect arguments */
+ if (nargs == ARG_ERROR) { /* End of input */
+ ACE_OS::free( arglist_pre[ 0]);
+ longjmp( jump, 1);
+ }
+ }
+ break;
+ } /* defp->nargs switch */
+
+ if (defp->nargs > 0)
+ substitute_pre( defp); /* Do actual arguments */
+ else
+ unget_string( defp->repl, defp->name);
+
+ if (mcpp_debug & EXPAND)
+ dump_unget( "replace_pre exit");
+ if (defp->nargs >= 0)
+ ACE_OS::free( arglist_pre[ 0]);
+ return TRUE;
+}
+
+static void substitute_pre(
+ DEFBUF * defp /* Current macro being replaced */
+)
+/*
+ * Stuff the macro body, substituting formal parameters with actual arguments.
+ */
+{
+ int c; /* Current character */
+ FILEINFO * file; /* Funny #include */
+ char * out_end; /* -> output buffer end */
+ char * in_p; /* -> replacement text */
+ char * out_p; /* -> macro output buff */
+
+ file = get_file( defp->name, (size_t) (NMACWORK + 1));
+ in_p = defp->repl; /* -> macro replacement */
+ out_p = file->buffer; /* -> output buffer */
+ out_end = file->buffer + NMACWORK; /* -> buffer end */
+
+ while ((c = *in_p++) != EOS) {
+ if (c == MAC_PARM) {
+ c = (*in_p++ & UCHARMAX) - 1; /* Parm number */
+ /*
+ * Substitute formal parameter with actual argument.
+ */
+ if (out_end <= (out_p + ACE_OS::strlen( arglist_pre[ c])))
+ goto nospace;
+ out_p = stpcpy( out_p, arglist_pre[ c]);
+ } else {
+ *out_p++ = c;
+ }
+ if (out_end <= out_p)
+ goto nospace;
+ }
+
+ *out_p = EOS;
+ file->buffer = xrealloc( file->buffer, ACE_OS::strlen( file->buffer) + 1);
+ file->bptr = file->buffer; /* Truncate buffer */
+ if (mcpp_debug & EXPAND)
+ dump_string( "substitute_pre macroline", file->buffer);
+ return;
+
+nospace:
+ *out_p = EOS;
+ diag_macro( CERROR, macbuf_overflow, defp->name, 0L, file->buffer, defp
+ , 0);
+ longjmp( jump, 1);
+}
+
+
+/*
+ * C O M M O N R O U T I N E S
+ * f o r S T A N D A R D a n d p r e - S T A N D A R D M o d e s
+ */
+
+static int collect_args(
+ const DEFBUF * defp, /* Definition of the macro */
+ char ** arglist /* Pointers to actual arguments */
+)
+/*
+ * Collect the actual arguments for the macro, checking for correct number
+ * of arguments.
+ * Variable arguments (on Standard modes) are read as a merged argument.
+ * Return number of arguments, or ARG_ERROR on error of unterminated macro.
+ * collect_args() may read over to the next line unless 'in_directive' is
+ * set to TRUE.
+ * collect_args() may read over into file->parent to complete a macro call
+ * unless stopped by RT_END (provided the "file" is macro). This is a key
+ * trick of STD mode macro expansion. Meanwhile, POST_STD mode limits the
+ * arguments in the "file" (macro or not).
+ * Note: arglist[ n] may be reallocated by collect_args().
+ */
+{
+ const char * name = defp->name;
+ char * argp = arglist[ 0]; /* Pointer to an argument */
+ char * arg_end; /* End of arguments buffer */
+ char * valid_argp = 0; /* End of valid arguments */
+ char * sequence; /* Token sequence for diagnostics */
+ char * seq; /* Current pointer into 'sequence' */
+ char * seq_end; /* Limit of buffer */
+ int args; /* Number of arguments expected */
+ int nargs = 0; /* Number of collected args */
+ int var_arg = defp->nargs & VA_ARGS; /* Variable args */
+ int more_to_come = FALSE; /* Next argument is expected*/
+ int ret = ARG_ERROR; /* Return value */
+ int c;
+
+ if (mcpp_debug & EXPAND)
+ dump_unget( "collect_args entry");
+ args = (defp->nargs == DEF_PRAGMA) ? 1 : (defp->nargs & ~AVA_ARGS);
+ if (args == 0) /* Need no argument */
+ valid_argp = argp;
+ *argp = EOS; /* Make sure termination */
+ arg_end = argp + NMACWORK/2;
+ seq = sequence = arg_end + IDMAX; /* Use latter half of argp */
+ seq_end = seq + NMACWORK/2;
+ seq = stpcpy( seq, name);
+ *seq++ = '(';
+ /*
+ * in_getarg is set TRUE while getting macro arguments, for the sake of
+ * diagnostic's convenience.
+ * in_getarg is used only in STD mode.
+ */
+ if (mcpp_mode == STD)
+ in_getarg = TRUE;
+
+ while (1) {
+ c = squeeze_ws( &seq); /* Skip white spaces */
+ if (c == ')' || c == ',')
+ scan_token( c, &seq, seq_end); /* Ensure token parsing */
+ else
+ *seq = EOS;
+
+ switch (c) { /* First character of token */
+ case ')':
+ if (! more_to_come) /* Zero argument */
+ break; /* Else fall through */
+ case ',': /* Empty argument */
+ if (warn_level & 2)
+ diag_macro( CWARN, empty_arg, sequence, 0L, 0, defp, 0);
+ if (standard && var_arg && nargs == args - 1) {
+ /* Variable arguments begin with an empty argument */
+ c = get_an_arg( c, &argp, arg_end, &seq, 1);
+ } else {
+ if (mcpp_mode == STD)
+ *argp++ = RT_END;
+ *argp++ = EOS;
+ }
+ if (++nargs == args)
+ valid_argp = argp;
+ if (c == ',') {
+ more_to_come = TRUE;
+ continue;
+ } else { /* ')' */
+ break;
+ }
+ case '\n': /* Unterminated macro call in control line */
+ unget_ch(); /* Fall through */
+ case RT_END: /* Error of missing ')' */
+ diag_macro( CERROR, unterm_macro, sequence, 0L, 0, defp, 0);
+ /* Fall through */
+ case CHAR_EOF: /* End of file in macro call*/
+ goto arg_ret; /* Diagnosed by at_eof() */
+ default: /* Nomal argument */
+ break;
+ }
+
+ if (c == ')') /* At end of all args */
+ break;
+
+ c = get_an_arg( c, &argp, arg_end, &seq,
+ (var_arg && nargs == args - 1) ? 1 : 0);
+
+ if (++nargs == args)
+ valid_argp = argp; /* End of valid arguments */
+ if (c == ')')
+ break;
+ if (c == 0) /* End of file */
+ goto arg_ret; /* Diagnosed by at_eof() */
+ if (c == -1) { /* Untermanated macro call */
+ diag_macro( CERROR, unterm_macro, sequence, 0L, 0, defp, 0);
+ goto arg_ret;
+ }
+ more_to_come = (c == ',');
+ } /* Collected all arguments */
+
+ if (nargs == 0 && args == 1) { /* Only and empty argument */
+ if (warn_level & 2)
+ diag_macro( CWARN, empty_arg, sequence, 0L, 0, defp, 0);
+ } else if (nargs != args) { /* Wrong number of arguments*/
+ if (mcpp_mode != OLD_PREP || (warn_level & 1)) {
+ if ((standard && var_arg && (nargs == args - 1))
+ /* Absence of variable arguments */
+ || (mcpp_mode == OLD_PREP)) {
+ if (warn_level & 1)
+ diag_macro( CWARN, narg_error, nargs < args ? "Less"
+ : "More", (long) args, sequence, defp, 0);
+ } else {
+ diag_macro( CERROR, narg_error, nargs < args ? "Less" : "More"
+ , (long) args, sequence, defp, 0);
+ }
+ }
+ }
+ if (args < nargs) {
+ argp = valid_argp; /* Truncate excess arguments*/
+ } else {
+ for (c = nargs; c < args; c++) {
+ if (mcpp_mode == STD)
+ *argp++ = RT_END; /* For rescan() */
+ *argp++ = EOS; /* Missing arguments */
+ }
+ if (c == 0)
+ argp++; /* Ensure positive length */
+ }
+ arglist[ 0] = argp
+ = xrealloc( arglist[ 0], (size_t)(argp - arglist[ 0]));
+ /* Use memory sparingly */
+ for (c = 1; c < args; c++)
+ arglist[ c] = argp += ACE_OS::strlen( argp) + 1;
+
+ ret = nargs;
+arg_ret:
+ if (mcpp_debug & EXPAND) {
+ if (nargs > 0)
+ dump_args( "collect_args exit"
+ , nargs < args ? nargs : args, arglist);
+ dump_unget( "collect_args exit");
+ }
+ if (mcpp_mode == STD)
+ in_getarg = FALSE;
+
+ return ret;
+}
+
+static int get_an_arg(
+ int c,
+ char ** argpp, /* Address of pointer into argument list */
+ char * arg_end, /* End of argument list buffer */
+ char ** seqp, /* Buffer for diagnostics */
+ int var_arg /* 1 on __VA_ARGS__, 0 on others*/
+)
+/*
+ * Get an argument of macro into '*argpp', return the next punctuator.
+ * Variable arguments are read as a merged argument.
+ */
+{
+ int end_an_arg = FALSE; /* End-of-an-arg flag */
+ int paren = var_arg; /* For embedded ()'s */
+ int token_type;
+ char * prevp;
+ char * argp = *argpp;
+
+ while (1) {
+ if (c == '\n' /* In control line */
+ || c == RT_END) { /* Boundary of rescan (in STD mode) */
+ if (c == '\n')
+ unget_ch();
+ break;
+ }
+ token_type = scan_token( c, (prevp = argp, &argp), arg_end);
+ /* Scan the next token */
+ switch (c) {
+ case '(' : /* Worry about balance */
+ paren++; /* To know about commas */
+ break;
+ case ')' : /* Other side too */
+ if (paren-- == var_arg) /* At the end? */
+ end_an_arg = TRUE; /* Else more to come */
+ break;
+ case ',' :
+ if (paren == 0) /* Comma delimits arg */
+ end_an_arg = TRUE;
+ break;
+ case CHAR_EOF: /* Unexpected EOF */
+ return 0;
+ default : /* Any token */
+ if (mcpp_mode == STD && ! compat_mode && token_type == NAM
+ && c != IN_SRC && c != DEF_MAGIC && infile->fp) {
+ ACE_OS::memmove( prevp + 1, prevp, (size_t) (argp++ - prevp));
+ *prevp = IN_SRC;
+ } /* Mark that the name is read from source file */
+ break;
+ } /* End of switch */
+
+ if (end_an_arg) /* End of an argument */
+ break;
+ c = squeeze_ws( &argp); /* To the next token */
+ } /* Collected an argument*/
+
+ *argp = EOS;
+ *seqp = stpcpy( *seqp, *argpp); /* Save the sequence */
+ if (c == '\n' || c == RT_END)
+ return -1; /* Unterminated macro */
+ argp--; /* Remove the punctuator*/
+ while (*argpp < argp && *(argp - 1) == ' ')
+ --argp; /* Remove trailing blanks */
+ if (mcpp_mode == STD)
+ *argp++ = RT_END; /* For rescan() */
+ *argp++ = EOS; /* Terminate an argument*/
+ *argpp = argp;
+ return c;
+}
+
+static int squeeze_ws(
+ char ** out /* pointer to output pointer */
+)
+/*
+ * Squeeze white spaces to one space.
+ * White spaces are ' ' ('\t', '\r', '\v', '\f' converted to ' ' by get_ch()),
+ * and '\n' unless in_directive is set.
+ * COM_SEP is skipped. TOK_SEPs are squeezed to one TOK_SEP.
+ * If white spaces are found and 'out' is not 0, write a space to *out and
+ * increment *out.
+ * Return the next character.
+ */
+{
+ int c;
+ int space = 0;
+ FILEINFO * file = infile;
+ int tsep = 0;
+ FILE * fp = infile->fp;
+
+ while ((char_type[ c = get_ch()] & SPA) && (! standard
+ || (mcpp_mode == POST_STD && file == infile)
+ || (mcpp_mode == STD
+ && ((macro_line != 0 && macro_line != MACRO_ERROR)
+ || file == infile)))) {
+ if (c == '\n') {
+ if (in_directive) /* If scanning control line */
+ break; /* do not skip newline. */
+ else
+ wrong_line = TRUE;
+ }
+ if (c == TOK_SEP) {
+ if (mcpp_mode == STD)
+ tsep++;
+ continue; /* Skip COM_SEP in OLD_PREP mode */
+ }
+ space++;
+ }
+
+ if (out) {
+ if (space) /* Write a space to output pointer */
+ *(*out)++ = ' '; /* and increment the pointer. */
+ if (tsep)
+ *(*out)++ = TOK_SEP;
+ }
+ if (mcpp_mode == POST_STD && file != infile) {
+ unget_ch(); /* Arguments cannot cross "file"s */
+ c = fp ? CHAR_EOF : RT_END; /* EOF is diagnosed by at_eof() */
+ } else if (mcpp_mode == STD && macro_line == MACRO_ERROR
+ && file != infile) { /* EOF */
+ unget_ch(); /* diagnosed by at_eof() or only */
+ c = CHAR_EOF; /* name of a function-like macro. */
+ } /* at_eof() resets macro_line on error */
+ return c; /* Return the next character */
+}
+
+static void skip_macro( void)
+/*
+ * Clear the stacked (i.e. half-expanded) macro, called on macro error.
+ */
+{
+ if (infile == 0) /* End of input */
+ return;
+ if (infile->fp) /* Source file */
+ return;
+ while (infile->fp == 0) { /* Stacked stuff */
+ infile->bptr += ACE_OS::strlen( infile->bptr);
+ get_ch(); /* To the parent "file" */
+ }
+ unget_ch();
+}
+
+static void diag_macro(
+ int severity, /* Error or warning */
+ const char * format,
+ const char * arg1,
+ long arg2,
+ const char * arg3,
+ const DEFBUF * defp1, /* Macro causing the problem 1 */
+ const DEFBUF * defp2 /* 2 */
+)
+/*
+ * Supplement macro information for diagnostic.
+ */
+{
+
+ if (defp1 && defp1->name != macro_name)
+ expanding( defp1->name, FALSE);
+ /* Inform of the problematic macro call */
+ if (defp2 && defp2->name != macro_name)
+ expanding( defp2->name, FALSE);
+ if (severity == CERROR)
+ cerror( format, arg1, arg2, arg3);
+ else
+ cwarn( format, arg1, arg2, arg3);
+}
+
+static void dump_args(
+ const char * why,
+ int nargs,
+ char ** arglist
+)
+/*
+ * Dump arguments list.
+ */
+{
+ int i;
+
+ mcpp_fprintf( DBG, "dump of %d actual arguments %s\n", nargs, why);
+ for (i = 0; i < nargs; i++) {
+ mcpp_fprintf( DBG, "arg[%d]", i + 1);
+ dump_string( 0, arglist[ i]);
+ }
+}
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/internal.H b/TAO/TAO_IDL/contrib/mcpp/internal.H
new file mode 100644
index 00000000000..13586364722
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/internal.H
@@ -0,0 +1,512 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * I N T E R N A L . H
+ * I n t e r n a l D e f i n i t i o n s f o r M C P P
+ *
+ * In general, definitions in this file should not be changed by implementor.
+ */
+
+#ifndef SYSTEM_H
+ #error "system.H" must be included prior to "internal.H"
+#endif
+
+#include "mcpp_lib.h" /* External interface when used as library */
+
+#define EOS '\0' /* End of string */
+#define CHAR_EOF 0 /* Returned by get_ch() on eof */
+
+#define VA_ARGS (UCHARMAX + 1) /* Signal of variable arguments */
+#define GVA_ARGS (VA_ARGS * 2) /* GCC3-specific variable args */
+#define AVA_ARGS (VA_ARGS | GVA_ARGS)/* Any variable arguments */
+#define DEF_PRAGMA (-1 - AVA_ARGS) /* _Pragma() pseudo-macro */
+#define DEF_NOARGS (-2 - AVA_ARGS) /* #define foo vs #define foo() */
+
+/*
+ * The following may need to change if the host system doesn't use ASCII.
+ * These magic characters must be control characters which can't be used
+ * in source file.
+ */
+/* In STD and POST_STD modes (IN_SRC and TOK_SEP are for STD mode only). */
+#define DEF_MAGIC 0x19 /* Magic for #defines */
+#define IN_SRC 0x1A /* Magic of name from source */
+#define RT_END 0x1C /* Magic of macro rescan boundary */
+#define ST_QUOTE 0x1D /* Magic for stringizing */
+#define CAT 0x1E /* Token concatenation delim. */
+#define TOK_SEP 0x1F /* Magic to wrap expanded macro */
+/* In OLD_PREP mode. */
+#define COM_SEP 0x1F /* Comment as token separator */
+
+#define MAC_PARM 0x7F /* Macro formals signal */
+
+/* Special character types */
+#define LET 1 /* Letter (alphabet and _) */
+#define DIG 2 /* Digit */
+#define DOT 4 /* . might start a number */
+#define PUNC 8 /* Punctuators and operators */
+#define QUO 16 /* Both flavors of quotation ",'*/
+#define SPA 32 /* White spaces */
+
+/*
+ * Codes for operators used in #if expression.
+ * The value is stored in 'openum'.
+ */
+#define INV 0 /* Invalid, must be zero */
+#define OP_EOE INV /* End of expression */
+#define VAL 1 /* Value (operand) */
+#define OP_LPA 2 /* ( */
+/* The following are unary. */
+#define FIRST_UNOP OP_PLU /* First unary operator */
+#define OP_PLU 3 /* + (ANSI Standard) */
+#define OP_NEG 4 /* - */
+#define OP_COM 5 /* ~ */
+#define OP_NOT 6 /* ! */
+#define LAST_UNOP OP_NOT /* Last unary operator */
+/* The following are binary. */
+#define FIRST_BINOP OP_MUL /* First binary operator */
+#define OP_MUL 7 /* * */
+#define OP_DIV 8 /* / */
+#define OP_MOD 9 /* % */
+#define OP_ADD 10 /* + */
+#define OP_SUB 11 /* - */
+#define OP_SL 12 /* << */
+#define OP_SR 13 /* >> */
+#define OP_LT 14 /* < */
+#define OP_LE 15 /* <= */
+#define OP_GT 16 /* > */
+#define OP_GE 17 /* >= */
+#define OP_EQ 18 /* == */
+#define OP_NE 19 /* != */
+#define OP_AND 20 /* & */
+#define OP_XOR 21 /* ^ */
+#define OP_OR 22 /* | */
+#define OP_ANA 23 /* && */
+#define OP_ORO 24 /* || */
+#define OP_QUE 25 /* ? */
+#define OP_COL 26 /* : */
+#define LAST_BINOP OP_COL /* Last binary operator */
+/* Parenthesis */
+#define OP_RPA 27 /* ) */
+#define OP_END 28 /* End of expression marker */
+#define OP_FAIL (OP_END + 1) /* For error returns */
+
+/*
+ * The following are operators used in macro definition only.
+ */
+/* In STD and POST_STD modes. */
+#define OP_STR 30 /* # */
+#define OP_CAT 31 /* ## */
+#define OP_ELL 32 /* ... */
+
+/*
+ * The following are C source operators or punctuators,
+ * not preprocessing operators.
+ * Note: "sizeof", "defined" are read as identifier for convenience.
+ */
+#define OP_1 33 /* Any other single byte ops or puncs */
+ /* =, ., ;, [, ], {, }, ',' */
+#define OP_2 34 /* Any other two bytes operators */
+ /* &=, |=, ++, +=, --, -=, ->, %=, *=, /=, ^=, */
+#define OP_3 35 /* Three bytes operators : <<=, >>= */
+/*
+ * The following are operators spelled in digraphs.
+ */
+/* In STD and POST_STD modes. */
+#define OP_LBRACE_D 0x40 /* <% i.e. { */
+#define OP_RBRACE_D 0x41 /* %> i.e. } */
+#define OP_LBRCK_D 0x42 /* <: i.e. [ */
+#define OP_RBRCK_D 0x43 /* :> i.e. ] */
+#define OP_SHARP_D 0x44 /* %: i.e. # */
+#define OP_DSHARP_D 0x45 /* %:%: i.e. ## */
+#define OP_DIGRAPH 0x40 /* (OP_*_D & OP_DIGRAPH) == 0x40 */
+
+/*
+ * The following are for lexical scanning only.
+ */
+/* Token types */
+#define NO_TOKEN 0
+#define NAM 65 /* Identifier (name, keyword) */
+#define NUM 66 /* Preprocessing number */
+#define STR 67 /* Character string literal */
+#define CHR 69 /* Integer character constant */
+
+/* In STD and POST_STD modes. */
+#define WSTR 68 /* Wide string literal */
+#define WCHR 70 /* Wide character constant */
+
+#define OPE 71 /* Operator or punctuator */
+#define SPE 72 /* Unknown token (@ or others) */
+#define SEP 73 /* Token separator or magics */
+
+/*
+ * The following are values of 'debug' variable which is set by the
+ * arguments of #pragma MCPP debug directive.
+ */
+#define PATH 1
+#define TOKEN 2
+#define EXPAND 4
+#define IF 8
+#define EXPRESSION 16
+#define GETC 32
+#define MEMORY 64
+
+/* MB_ERROR signals wrong multi-byte character sequence. */
+#define MB_ERROR 0x8000
+
+/*
+ * The DEFBUF structure stores information about #defined macros.
+ * Note that DEFBUF->parmnames is parameter names catenated with commas,
+ * which is saved for the check of redefinition for STD mode.
+ * 'parmnames' and 'repl' are allocated to the area succeding to name.
+ */
+typedef struct defbuf {
+ struct defbuf * link; /* Pointer to next def in chain */
+ short nargs; /* Number of parameters */
+ char * parmnames; /* -> Parameter names catenated by ',' */
+ char * repl; /* Pointer to replacement text */
+ const char * dir; /* The macro is defined in */
+ const char * fname; /* dir/fname source file */
+ long mline; /* at the line. */
+ char push; /* Push level indicator */
+ char name[1]; /* Macro name */
+} DEFBUF;
+
+/*
+ * The FILEINFO structure stores information about open files and macros
+ * being expanded.
+ */
+typedef struct fileinfo {
+ char * bptr; /* Current pointer into buffer */
+ long line; /* Current line number of file */
+ FILE * fp; /* Source file if non-null */
+ long pos; /* Position next to #include */
+ struct fileinfo * parent; /* Link to includer */
+ struct ifinfo * initif; /* Initial ifstack (return there on EOF)*/
+ const char ** dirp; /* Include directory the file resides */
+ const char * real_fname; /* Real file name */
+ char * filename; /* File/macro name (maybe changed) */
+ char * buffer; /* Buffer of current input line */
+#if MCPP_LIB
+ /* Save output functions during push/pop of #includes */
+ int (* last_fputc) ( int c, OUTDEST od);
+ int (* last_fputs) ( const char * s, OUTDEST od);
+ int (* last_fprintf)( OUTDEST od, const char * format, ...);
+#endif
+} FILEINFO;
+
+/*
+ * IFINFO stores information of conditional compilation.
+ */
+typedef struct ifinfo {
+ int stat; /* State of compilation */
+ long ifline; /* Line #if started */
+ long elseline; /* Line #else started */
+} IFINFO;
+
+/*
+ * These bits are set in IFINFO.stat
+ */
+#define WAS_COMPILING 1 /* TRUE if compile set at entry */
+#define ELSE_SEEN 2 /* TRUE when #else processed */
+#define TRUE_SEEN 4 /* TRUE when #if TRUE processed */
+
+#define compiling ifstack[0].stat
+
+#define FP2DEST(fp) \
+ (fp == fp_out) ? OUT : \
+ ((fp == fp_err) ? ERR : \
+ ((fp == fp_debug) ? DBG : \
+ ((OUTDEST) -1)))
+
+/* VAL_SIGN structure stores information about evaluated number. */
+typedef struct val_sign {
+ expr_t val; /* Value */
+ int sign; /* Signed, unsigned, error */
+} VAL_SIGN;
+
+/* Values of VAL_SIGN.sign. */
+#define SIGNED 1
+#define UNSIGNED 0
+#define VAL_ERROR (-1)
+
+/* Value of macro_line on macro call error. */
+#define MACRO_ERROR (-1L)
+
+/*
+ * Values of insert_sep (flag of insertion of token separator).
+ * Used only in POST_STD mode.
+ */
+#define NO_SEP 0 /* No separator is inserted */
+#define INSERT_SEP 1 /* Next get_ch() insert a separator */
+#define INSERTED_SEP 2 /* Last get_ch() Inserted a separator */
+
+#define str_eq(s1, s2) (strcmp(s1, s2) == 0)
+
+#ifndef IO_SUCCESS
+#define IO_SUCCESS 0
+#endif
+#ifndef IO_ERROR
+#define IO_ERROR (errno ? errno : 1)
+#endif
+
+/* For conv_case() */
+#define UPPER 1 /* To upper */
+#define LOWER 0 /* To lower */
+
+/*
+ * Externs
+ */
+extern int mcpp_mode; /* Mode of preprocessing */
+extern int cflag; /* -C option (keep comments) */
+extern int zflag; /* -Z option (no-output of included file) */
+extern int pflag; /* -P option (no #line output) */
+extern int qflag; /* -Q option (diag to mcpp.err) */
+extern int trig_flag; /* -3 option (toggle trigraphs) */
+extern int dig_flag; /* -2 option (toggle digraphs) */
+extern int stdc_val; /* Value of __STDC__ */
+extern long stdc_ver; /* Value of __STDC_VERSION__ */
+extern long cplus_val; /* Value of __cplusplus for C++ */
+extern int stdc2; /* cplus_val or stdc_ver >= 199901L */
+extern int stdc3; /* (stdc_ver or cplus_val) >= 199901L */
+extern int standard; /* mcpp_mode is STD or POST_STD */
+extern long str_len_min; /* Least maxmum of string len. */
+extern size_t id_len_min; /* Least maximum of ident len. */
+extern int n_mac_pars_min; /* Least maximum of num of pars.*/
+extern int exp_nest_min; /* Least maximum of expr nest */
+extern int blk_nest_min; /* Least maximum of block nest */
+extern int inc_nest_min; /* Least maximum of include nest*/
+extern long n_macro_min; /* Least maximum of num of macro*/
+extern long line_limit; /* Maximum source line number */
+extern int has_pragma; /* '_Pragma()' has been expanded*/
+extern int lang_asm; /* -a option (assembler source) */
+extern int std_line_prefix; /* #line in C source style */
+extern int warn_level; /* Level of warning */
+extern int errors; /* Error counter */
+extern long src_line; /* Current source line number */
+extern int wrong_line; /* Force #line to compiler */
+extern int newlines; /* Count of blank lines */
+extern int keep_comments; /* Don't remove comments */
+extern int include_nest; /* Nesting level of #include */
+extern const char * null; /* "" string for convenience */
+extern const char ** inc_dirp; /* Directory of #includer */
+extern const char * cur_fname; /* Current source file name */
+extern int no_output; /* Don't output included file */
+extern int in_directive; /* In process of #directive */
+extern int in_define; /* In #define line */
+extern int in_getarg; /* Collecting arguments of macro*/
+extern int in_include; /* In #include line */
+extern int compat_mode; /* Compatible macro recursion */
+extern long macro_line; /* Line number of macro call */
+extern char * macro_name; /* Currently expanding macro */
+extern int openum; /* Number of operator or punct. */
+extern IFINFO * ifptr; /* -> current ifstack item */
+extern FILEINFO * infile; /* Current input file or macro */
+extern int no_source_line; /* Do not output line in diag. */
+extern FILE * fp_in; /* Input stream to preprocess */
+extern FILE * fp_out; /* Output stream preprocessed */
+extern FILE * fp_err; /* Diagnostics stream */
+extern FILE * fp_debug; /* Debugging information stream */
+extern int insert_sep; /* Inserted token separator flag*/
+extern int mkdep; /* Output source file dependency*/
+extern int mbchar; /* Encoding of multi-byte char */
+extern int mbmask; /* Char type other than mbchar */
+extern int mbstart; /* 1st byte of mbchar (or shift)*/
+extern int bsl_in_mbchar; /* 2nd byte of mbchar has '\\' */
+extern int bsl_need_escape;/* '\\' in mbchar should be escaped */
+extern int mcpp_debug; /* Class of debug information */
+extern long in_asm; /* In #asm - #endasm block */
+extern jmp_buf error_exit; /* Exit on fatal error */
+extern char * workp; /* Free space in work[] */
+extern char * const work_end; /* End of work[] buffer */
+extern char identifier[]; /* Lastly scanned name */
+extern short * char_type; /* Character classifier */
+extern IFINFO ifstack[]; /* Information of #if nesting */
+extern char cur_fullname[]; /* Full name of current source */
+extern char work_buf[];
+ /* Temporary buffer for directive line and macro expansion */
+
+/* main.c */
+extern void sharp( void);
+ /* Output # line number */
+extern void un_predefine( int clearall);
+ /* Undefine predefined macros */
+extern void undef_a_predef( const char * name);
+ /* Remove a non-standard predef */
+
+/* directive.c */
+extern void directive( void);
+ /* Process #directive lines */
+extern DEFBUF * do_define( int ignore_redef);
+ /* Do #define directive */
+extern DEFBUF * look_id( const char * name);
+ /* Look for a #define'd thing */
+extern DEFBUF ** look_prev( const char * name, int * cmp);
+ /* Look for place to insert def.*/
+extern DEFBUF * look_and_install( const char * name, int numargs
+ , const char * parmnames, const char * repl);
+ /* Look and insert macro def. */
+extern DEFBUF * install_macro( const char * name, int numargs
+ , const char * parmnames, const char * repl, DEFBUF ** prevp, int cmp);
+ /* Install to symbol table */
+extern int undefine( const char * name);
+ /* Delete from symbol table */
+extern void dump_a_def( const char * why, const DEFBUF * dp, int newdef
+ , int dDflag, int comment, FILE * fp);
+ /* Dump a specific macro def */
+extern void dump_def( int dDflag, int comment);
+ /* Dump current macro defs */
+
+/* eval.c */
+extern expr_t eval_if( void);
+ /* Evaluate #if expression */
+extern VAL_SIGN * eval_num( const char * nump);
+ /* Evaluate preprocessing number*/
+
+/* expand.c */
+extern char * (* expand_macro)( DEFBUF * defp, char * out, char * out_end);
+ /* Expand a macro completely */
+extern void expand_init( void);
+ /* Initialize expand_macro() */
+extern DEFBUF * is_macro( char ** cp);
+ /* The sequence is a macro call?*/
+
+/* mbchar.c */
+extern size_t (* mb_read)( int c1, char ** in_pp, char ** out_pp);
+ /* Read mbchar sequence */
+extern const char * set_encoding( char * name, char * env, int pragma);
+ /* Multi-byte char encoding */
+extern void mb_init( void);
+ /* Initialize mbchar variables */
+extern uexpr_t mb_eval( char ** seq_pp);
+ /* Evaluate mbchar in #if */
+
+/* support.c */
+extern int get_unexpandable( int c, int diag);
+ /* Get next unexpandable token */
+extern void skip_nl( void);
+ /* Skip to the end of the line */
+extern int skip_ws( void);
+ /* Skip over white-spaces */
+extern int scan_token( int c, char ** out_pp, char * out_end);
+ /* Get the next token */
+extern char * scan_quote( int delim, char * out, char * out_end, int diag);
+ /* Scan a quoted literal */
+extern int id_operator( const char * name);
+ /* Check identifier-like ops */
+extern void expanding( const char * name, int to_be_freed);
+ /* Save macro name expanding */
+extern void clear_exp_mac( void);
+ /* Clear expanding macro infs */
+extern int get_ch( void);
+ /* Get the next char from input */
+extern int cnv_trigraph( char * in);
+ /* Do trigraph replacement */
+extern int cnv_digraph( char * in);
+ /* Convert digraphs to usual tok*/
+extern void unget_ch( void);
+ /* Push back the char to input */
+extern FILEINFO * unget_string( const char * text, const char * name);
+ /* Push back the string to input*/
+extern char * save_string( const char * text);
+ /* Stuff string in malloc mem. */
+extern FILEINFO * get_file( const char * name, size_t bufsize);
+ /* New FILEINFO initialization */
+extern char * (xmalloc)( size_t size);
+ /* Get memory or die */
+extern char * (xrealloc)( char * ptr, size_t size);
+ /* Reallocate memory or die */
+extern void cfatal( const char * format, const char * arg1, long arg2
+ , const char * arg3);
+ /* Print a fatal error and exit */
+extern void cerror( const char * format, const char * arg1, long arg2
+ , const char * arg3);
+ /* Print an error message */
+extern void cwarn( const char * format, const char * arg1, long arg2
+ , const char * arg3);
+ /* Print a warning message */
+extern void dump_string( const char * why, const char * text);
+ /* Dump text readably */
+extern void dump_unget( const char * why);
+ /* Dump all ungotten junk */
+/* Support for alternate output mechanisms (e.g. memory buffers) */
+extern int (* mcpp_fputc)( int c, OUTDEST od);
+extern int (* mcpp_fputs)( const char * s, OUTDEST od);
+extern int (* mcpp_fprintf)( OUTDEST od, const char *format, ...);
+
+/* system.c */
+extern void do_options( int argc, char ** argv, char ** in_pp
+ , char ** out_pp);
+ /* Process command line args */
+extern void at_start( void);
+ /* Commands prior to main input */
+extern void put_depend( const char * filename);
+ /* Output source dependency line*/
+extern int do_include( int next);
+ /* Process #include directive */
+extern void add_file( FILE * fp, const char * filename);
+ /* Chain the included file */
+extern void cur_file( void);
+ /* Output current source fname */
+extern void conv_case( char * name, char * lim, int upper);
+ /* Convert to upper/lower case */
+extern void put_info( void);
+ /* Putout compiler-specific info*/
+extern void do_pragma( void);
+ /* Process #pragma directive */
+extern void put_asm( void);
+ /* Putout an asm code line */
+extern void do_old( void);
+ /* Process older directives */
+extern void at_end( void);
+ /* Do the final commands */
+extern void print_heap( void);
+ /* Print blocks of heap memory */
+
+#if MCPP_LIB /* Setting to use mcpp as a subroutine */
+/* directive.c */
+extern void clear_symtable( void);
+ /* Free all macro definitions */
+extern void clear_filelist( void);
+ /* Free filename and directory list */
+/* The following 5 functions are to Initialize static variables. */
+/* directive.c */
+extern void init_directive( void);
+/* eval.c */
+extern void init_eval( void);
+/* support.c */
+extern void init_support( void);
+/* system.c */
+extern void init_system( void);
+#if NEED_GETOPT
+/* lib.c */
+extern void init_lib( void);
+#endif
+#endif
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/lib.cpp b/TAO/TAO_IDL/contrib/mcpp/lib.cpp
new file mode 100644
index 00000000000..36eaf1b4e9b
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/lib.cpp
@@ -0,0 +1,130 @@
+/* $Id$
+ * Redistribution and use of this code in source and binary forms, with or
+ * without modification, are freely permitted. [Kiyoshi Matsui]
+ */
+
+/*
+ * L I B . C
+ * L i b r a r y R o u t i n e s
+ *
+ * Some variation of standard library functions.
+ * Some standard functions for the library which has not those or the library
+ * which has only non-conforming ones.
+ */
+
+#if HAVE_CONFIG_H
+#include "configed.H"
+#else
+#include "noconfig.H"
+#endif
+
+#if NEED_GETOPT
+
+#include "system.H"
+#include "internal.H"
+
+/*
+ * Note: The getopt() of glibc should not be used since the specification
+ * differs from the standard one.
+ * Use this getopt() for this cpp.
+ */
+
+/* Based on the public-domain-software released by AT&T. */
+
+#define OPTERR( s, c) if (opterr) { \
+ mcpp_fputs( argv[0], ERR); \
+ mcpp_fputs( s, ERR); \
+ mcpp_fputc( c, ERR); \
+ mcpp_fputc( '\n', ERR); \
+ }
+
+int optind = 1;
+int opterr = 1;
+int optopt;
+char * optarg;
+
+#if MCPP_LIB
+void init_lib( void)
+{
+ optind = 1;
+ opterr = 1;
+}
+#endif
+//FUZZ: disable check_for_lack_ACE_OS
+int getopt(
+ int argc,
+ char * const * argv,
+ const char * opts
+)
+//FUZZ: enable check_for_lack_ACE_OS
+/*
+ * Get the next option (and it's argument) from the command line.
+ */
+{
+ const char * const error1 = ": option requires an argument --";
+ const char * const error2 = ": illegal option --";
+ static int sp = 1;
+ int c;
+ const char * cp;
+
+ if (sp == 1) {
+ if (argc <= optind ||
+ argv[ optind][ 0] != '-' || argv[ optind][ 1] == '\0') {
+ return EOF;
+ } else if (ACE_OS::strcmp( argv[ optind], "--") == 0) {
+ optind++;
+ return EOF;
+ }
+ }
+/* optopt = c = (unsigned char) argv[ optind][ sp]; */
+ optopt = c = argv[ optind][ sp] & UCHARMAX;
+ if (c == ':' || (cp = ACE_OS::strchr( opts, c)) == 0) {
+ OPTERR( error2, c)
+ if (argv[ optind][ ++sp] == '\0') {
+ optind++;
+ sp = 1;
+ }
+ return '?';
+ }
+ if (*++cp == ':') {
+ if (argv[ optind][ sp+1] != '\0') {
+ optarg = &argv[ optind++][ sp+1];
+ } else if (argc <= ++optind) {
+ OPTERR( error1, c)
+ sp = 1;
+ return '?';
+ } else {
+ optarg = argv[ optind++];
+ }
+ sp = 1;
+ } else {
+ if (argv[ optind][ ++sp] == '\0') {
+ sp = 1;
+ optind++;
+ }
+ optarg = 0;
+ }
+ return c;
+}
+
+#endif
+
+#if ! HOST_HAVE_STPCPY
+
+char * stpcpy(
+ char * dest,
+ const char * src
+)
+/*
+ * Copy the string and return the advanced pointer.
+ */
+{
+ const char * s;
+ char * d;
+
+ for (s = src, d = dest; (*d++ = *s++) != '\0'; )
+ ;
+ return d - 1;
+}
+
+#endif
diff --git a/TAO/TAO_IDL/contrib/mcpp/main.cpp b/TAO/TAO_IDL/contrib/mcpp/main.cpp
new file mode 100644
index 00000000000..28ee2a632c2
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/main.cpp
@@ -0,0 +1,1128 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * M A I N . C
+ * M C P P M a i n P r o g r a m
+ *
+ * The main routine and it's supplementary routines are placed here.
+ * The post-preprocessing routines are also placed here.
+ */
+
+#if PREPROCESSED /* Use "pre-preprocessed" header */
+#include "mcpp.H"
+#else
+#include "system.H"
+#include "internal.H"
+#endif
+
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_stdlib.h"
+
+ /* Function pointer to expand_macro() functions. */
+ char * (*expand_macro)( DEFBUF * defp, char * out, char * out_end);
+
+ int mcpp_mode = STD; /* Mode of preprocessing */
+
+ int cflag = FALSE; /* -C option (keep comments) */
+ int zflag = FALSE; /* -i option (no output of included file) */
+ int pflag = FALSE; /* -P option (no #line output) */
+ int qflag = FALSE; /* -Q option (diagnostics to "mcpp.err") */
+ int trig_flag = TRIGRAPHS_INIT; /* -3 option (trigraphs)*/
+ int dig_flag = DIGRAPHS_INIT; /* -2 option (digraphs) */
+ long cplus_val = 0L; /* Value of __cplusplus for C++ */
+ long stdc_ver = 0L; /* Value of __STDC_VERSION__ */
+ int stdc_val = 0; /* Value of __STDC__ */
+ int stdc2; /* cplus_val || stdc_ver >= 199901L */
+ int stdc3; /* cplus_val >= 199901L || stdc_ver >= 199901L.
+ (cplus_val >= 199901L) specifies compatible mode to C99 (extended
+ feature of this preprocessor) */
+ int standard = TRUE; /* TRUE, if mcpp_mode is STD or POST_STD */
+
+/*
+ * lang_asm allows the following non-standard features.
+ * 1. #non-directive.
+ * 2. <newline> in a string-literal.
+ * 3. invalid pp-token generated by ## operator.
+ * lang_asm is not available in POST_STD mode.
+ */
+ int lang_asm = FALSE; /* -a option (assembler source) */
+ int std_line_prefix = STD_LINE_PREFIX;
+ /* Output line and file information in C source style */
+
+/*
+ * Translation limits specified C90, C99 or C++.
+ */
+ /* The following three values are temporarily set for do_options() */
+ long str_len_min = NBUFF; /* Least maxmum of string len. */
+ size_t id_len_min = IDMAX; /* Least maximum of ident len. */
+ int n_mac_pars_min = NMACPARS; /* Least maximum of num of params. */
+ int exp_nest_min; /* Least maximum of expr nest */
+ int blk_nest_min; /* Least maximum of block nest */
+ int inc_nest_min; /* Least maximum of include nest*/
+ long n_macro_min; /* Least maximum of num of macros */
+
+ long line_limit; /* Maximum source line number */
+
+/*
+ * Commonly used global variables:
+ * src_line is the current input line number.
+ * wrong_line is set in many places when the actual output line is out of
+ * sync with the numbering, e.g, when expanding a macro with an
+ * embedded newline.
+ * identifier holds the last identifier scanned (which might be a candidate
+ * for macro expansion).
+ * errors is the running mcpp error counter.
+ * infile is the head of a linked list of input files (extended by
+ * #include and macros being expanded). 'infile' always points
+ * to the current file/macro. 'infile->parent' to the includer,
+ * etc. 'infile->fp' is NULL if this input stream is a macro.
+ * inc_dirp Directory of #includer with trailing PATH_DELIM. This points
+ * to one of incdir[] or to the current directory (represented as
+ * "". This should not be 0.
+ */
+ long src_line; /* Current line number */
+ int wrong_line; /* Force #line to compiler */
+ int newlines; /* Count of blank lines */
+ int errors = 0; /* Cpp error counter */
+ int warn_level = -1; /* Level of warning (have to initialize)*/
+ FILEINFO * infile = 0; /* Current input file */
+ int include_nest; /* Nesting level of #include */
+ const char * null = ""; /* "" string for convenience */
+ const char ** inc_dirp; /* Directory of #includer */
+ const char * cur_fname; /* Current source file name */
+ /* cur_fname is not rewritten by #line directive */
+ char cur_fullname[ FILENAMEMAX + 1];
+ /* Full path of current source file (i.e. *inc_dirp/cur_fname) */
+ int no_source_line; /* Do not output line in diag. */
+ char identifier[ IDMAX + IDMAX/8]; /* Current identifier */
+ int mcpp_debug = 0; /* != 0 if debugging now */
+
+/*
+ * in_directive is set TRUE while a directive line is scanned by directive().
+ * It modifies the behavior of squeeze_ws() in expand.c so that newline is
+ * not skipped even if getting macro arguments.
+ */
+ int in_directive = FALSE; /* TRUE scanning directive line */
+ int in_define = FALSE; /* TRUE scanning #define line */
+ int in_getarg = FALSE; /* TRUE collecting macro arguments */
+ int in_include = FALSE; /* TRUE scanning #include line */
+ long in_asm = 0L; /* Starting line of #asm - #endasm block*/
+
+/*
+ * macro_line is set to the line number of start of a macro call while
+ * expanding the macro, else set to 0. Line number is remembered for
+ * diagnostics of unterminated macro call. On unterminated macro call
+ * macro_line is set to MACRO_ERROR.
+ */
+ long macro_line = 0L;
+/*
+ * macro_name is the currently expanding macro.
+ */
+ char * macro_name;
+
+/*
+ * compat_mode is set to TRUE, if recursive macro call is expanded more
+ * than Standard's specification. This mode is compatible to GCC and
+ * some other implementations.
+ */
+ int compat_mode = FALSE;
+
+/*
+ * openum is the return value of scan_op() in support.c.
+ */
+ int openum;
+
+/*
+ * mkdep means to output source file dependency line, specified by -M*
+ * option. The OR of the following values is used.
+ * MD_MKDEP (1) : Output dependency line.
+ * MD_SYSHEADER(2) : Print also system headers or headers with
+ * absolute path not only user headers.
+ * MD_FILE (4) : Output to the file named *.d instead of fp_out.
+ * Normal output is done to fp_out as usual.
+ */
+ int mkdep = 0;
+
+/*
+ * If zflag is TRUE, no_output is incremented when a file is #included,
+ * and decremented when the file is finished.
+ * If no_output is larger than 0, processed files are not output, meanwhile
+ * the macros in the files are defined.
+ * If mkdep != 0 && (mkdep & MD_FILE) == 0, no_output is set to 1 initially.
+ */
+ int no_output = 0;
+
+/*
+ * keep_comments is set TRUE by the -C option. If TRUE, comments are written
+ * directly to the output stream. This is needed if the output from cpp is
+ * to be passed to lint (which uses commands embedded in comments). cflag
+ * contains the permanent state of the -C flag. keep_comments is always
+ * falsified when compilation is supressed by a false #if or when no_output
+ * is TRUE.
+ */
+ int keep_comments = 0; /* Write out comments flag */
+
+/*
+ * ifstack[] holds information about nested #if's. It is always accessed via
+ * ifptr->stat. The information is as follows:
+ * WAS_COMPILING state of compiling flag at outer level.
+ * ELSE_SEEN set TRUE when #else seen to prevent 2nd #else.
+ * TRUE_SEEN set TRUE when #if or #elif succeeds
+ * ifstack[0].stat holds the compiling flag. It is WAS_COMPILING if compila-
+ * tion is currently enabled. Note that this must be initialized to
+ * WAS_COMPILING.
+ */
+ IFINFO ifstack[ BLK_NEST + 1] = { {WAS_COMPILING, 0L, 0L}, };
+ /* Note: '+1' is necessary for the initial state. */
+ IFINFO * ifptr = ifstack; /* -> current ifstack[] */
+
+/*
+ * In POST_STD mode, insert_sep is set to INSERT_SEP when :
+ * 1. the next get_ch() shall insert a token separator.
+ * 2. unget_ch() has been called when insert_sep == INSERTED_SEP.
+ * set to INSERTED_SEP when :
+ * get_ch() has been called when insert_sep == INSERT_SEP.
+ * set to NO_SEP when :
+ * get_ch() has been called when insert_sep == INSERTED_SEP.
+ */
+ int insert_sep = NO_SEP;
+
+/*
+ * has_pragma is set to TRUE so as to execute _Pragma() operator when the
+ * psuedo macro _Pragma() is found.
+ */
+ int has_pragma = FALSE;
+
+/* File pointers for input and output. */
+ FILE * fp_in; /* Input stream to preprocess */
+ FILE * fp_out; /* Output stream preprocessed */
+ FILE * fp_err; /* Diagnostics stream */
+ FILE * fp_debug; /* Debugging information stream */
+
+/* Variables on multi-byte character encodings. */
+ int mbchar = MBCHAR; /* Encoding of multi-byte char */
+ int mbmask; /* Char type other than mbchar */
+ int mbstart; /* 1st byte of mbchar (or shift)*/
+ int bsl_in_mbchar; /* 2nd byte of mbchar has '\\' */
+ int bsl_need_escape; /* '\\' in MBCHAR should be escaped */
+ /* Function pointer to mb_read_*() functions. */
+ size_t (*mb_read)( int c1, char ** in_pp, char ** out_pp);
+
+ jmp_buf error_exit; /* Exit on fatal error */
+
+/*
+ * work_buf[] and workp are used to store one piece of text in a temporary
+ * buffer.
+ * To initialize storage, set workp = work_buf. Note that the work buffer is
+ * used by several subroutines -- be sure that your data won't be overwritten.
+ * work_buf[] is used for:
+ * 1. temporary buffer in macro expansion (exp_special(), expand_macro(),
+ * catenate())
+ * 2. temporary buffer in processing directive line.
+ */
+ char work_buf[ NWORK + IDMAX]; /* Work buffer */
+ char * workp; /* Pointer into work_buf[] */
+ char * const work_end = & work_buf[ NWORK];
+ /* End of buffer of work_buf[] */
+
+#define MBCHAR_IS_ESCAPE_FREE (SJIS_IS_ESCAPE_FREE && \
+ BIGFIVE_IS_ESCAPE_FREE && ISO2022_JP_IS_ESCAPE_FREE)
+
+#if MCPP_LIB
+static void init_main( void);
+ /* Initialize static variables */
+#endif
+static void init_defines( void);
+ /* Predefine macros */
+static void mcpp_main( void);
+ /* Main loop to process input lines */
+static void do_pragma_op( void);
+ /* Execute the _Pragma() operator */
+static void put_seq( char * begin, char * seq);
+ /* Put out the failed sequence */
+static char * de_stringize( char * in, char * out);
+ /* "De-stringize" for _Pragma() op. */
+static void putout( char * out);
+ /* May concatenate adjacent string */
+static void devide_line( char * out);
+ /* Devide long line for compiler */
+static void put_a_line( char * out);
+ /* Put out the processed line */
+#if ! HAVE_DIGRAPHS || ! MBCHAR_IS_ESCAPE_FREE
+static int post_preproc( char * out);
+ /* Post-preprocess for older comps */
+#if ! HAVE_DIGRAPHS
+static char * conv_a_digraph( char * cp);
+ /* Convert a digraph in place */
+#endif
+#if ! MBCHAR_IS_ESCAPE_FREE
+static char * esc_mbchar( char * str, char * str_end);
+ /* Insert \ before 2nd byte of SJIS */
+#endif
+#endif
+
+
+#if MCPP_LIB
+static void init_main( void)
+/* Initialize global variables on re-entering. */
+{
+ mcpp_mode = STD;
+ cflag = zflag = pflag = qflag = FALSE;
+ trig_flag = TRIGRAPHS_INIT;
+ dig_flag = DIGRAPHS_INIT;
+ cplus_val = stdc_ver = 0L;
+ stdc_val = 0;
+ standard = TRUE;
+ lang_asm = FALSE;
+ std_line_prefix = STD_LINE_PREFIX;
+ str_len_min = NBUFF;
+ id_len_min = IDMAX;
+ n_mac_pars_min = NMACPARS;
+ errors = 0;
+ warn_level = -1;
+ infile = 0;
+ in_directive = in_define = in_getarg = in_include = FALSE;
+ in_asm = 0L;
+ macro_line = 0L;
+ compat_mode = FALSE;
+ mcpp_debug = mkdep = no_output = keep_comments = 0;
+ ifstack[0].stat = WAS_COMPILING;
+ ifstack[0].ifline = ifstack[0].elseline = 0L;
+ ifptr = ifstack;
+ insert_sep = NO_SEP;
+ has_pragma = FALSE;
+ mbchar = MBCHAR;
+}
+
+int mcpp_lib_main
+#else
+int main
+#endif
+(
+ int argc,
+ char ** argv
+)
+{
+ char * in_file = 0;
+ char * out_file = 0;
+
+ if (setjmp( error_exit) == -1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "setjmp failed\n"));
+ goto fatal_error_exit;
+ }
+
+#if MCPP_LIB
+ /* Initialize static variables. */
+ init_main();
+ init_directive();
+ init_eval();
+ init_support();
+ init_system();
+#if NEED_GETOPT
+ init_lib();
+#endif
+#endif
+
+ fp_in = 0;
+ fp_out = 0;
+ fp_err = stderr;
+ fp_debug = stdout;
+ /*
+ * Debugging information is output to stdout in order to
+ * synchronize with preprocessed output.
+ */
+
+ inc_dirp = &null; /* Initialize to current (null) directory */
+ cur_fname = "(predefined)"; /* For predefined macros */
+ init_defines(); /* Predefine macros */
+ mb_init(); /* Should be initialized prior to get options */
+ do_options( argc, argv, &in_file, &out_file); /* Command line options */
+ /* Open input file, "-" means stdin. */
+ if (in_file != 0 && ! str_eq( in_file, "-")) {
+ if ((fp_in = ACE_OS::fopen( in_file, "r")) == 0) {
+ ACE_ERROR((LM_ERROR, "Can't open input file \"%s\".\n", in_file));
+#if MCPP_LIB
+ goto fatal_error_exit;
+#else
+ return( IO_ERROR);
+#endif
+ }
+ ACE_OS::strcpy( work_buf, in_file); /* Remember input filename */
+ } else {
+ ACE_OS::strcpy( work_buf, "<stdin>");
+ }
+
+ /* Open output file, "-" means stdout. */
+ if (out_file != 0 && ! str_eq( out_file, "-")) {
+ if ((fp_out = ACE_OS::fopen( out_file, "w")) == 0) {
+ ACE_ERROR((LM_ERROR, "Can't open output file \"%s\".\n", out_file));
+#if MCPP_LIB
+ goto fatal_error_exit;
+#else
+ return( IO_ERROR);
+#endif
+ }
+ }
+ if (qflag) { /* Redirect diagnostics */
+ if (ACE_OS::freopen( "mcpp.err", "a", fp_err) == 0) {
+ ACE_ERROR((LM_ERROR, "Can't open \"mcpp.err\"\n"));
+#if MCPP_LIB
+ goto fatal_error_exit;
+#else
+ return( IO_ERROR);
+#endif
+ }
+ }
+
+ if (fp_in == 0) fp_in = stdin;
+ if (fp_out == 0) fp_out = stdout;
+
+ add_file( fp_in, work_buf); /* "open" main input file */
+ infile->dirp = inc_dirp;
+ ACE_OS::strcpy( cur_fullname, work_buf);
+ if (mkdep && str_eq( infile->real_fname, "<stdin>") == FALSE)
+ put_depend( work_buf); /* Putout target file name */
+ at_start(); /* Do the pre-main commands */
+ mcpp_main(); /* Process main file */
+ if (mkdep)
+ put_depend( 0); /* Append '\n' to dependency line */
+ at_end(); /* Do the final commands */
+
+fatal_error_exit:
+#if MCPP_LIB
+ // ACE_DEBUG ((LM_DEBUG, "fatal_error_exit\n"));
+ /* Free malloced memory */
+ clear_filelist();
+ clear_symtable();
+#endif
+
+ if (mcpp_debug & MEMORY)
+ print_heap();
+ if (errors > 0 && no_source_line == FALSE) {
+ ACE_ERROR((LM_ERROR, "%d error%s in preprocessor.\n",
+ errors, (errors == 1) ? "" : "s"));
+ return IO_ERROR;
+ }
+
+ ACE_OS::fclose (fp_out);
+ return IO_SUCCESS; /* No errors or -E option set */
+}
+
+void sharp( void)
+/*
+ * Output a line number line.
+ */
+{
+ if (no_output || pflag || infile == 0)
+ goto sharp_exit;
+ if (keep_comments)
+ mcpp_fputc( '\n', OUT); /* Ensure to be on line top */
+ if (std_line_prefix)
+ mcpp_fprintf( OUT, "#line %ld", src_line);
+ else
+ mcpp_fprintf( OUT, "%s%ld", LINE_PREFIX, src_line);
+ cur_file();
+ mcpp_fputc( '\n', OUT);
+sharp_exit:
+ wrong_line = FALSE;
+}
+
+/*
+ * This is the table used to predefine target machine, operating system and
+ * compiler designators. It may need hacking for specific circumstances.
+ * The -N option supresses these definitions.
+ */
+typedef struct pre_set {
+ const char * name;
+ const char * val;
+} PRESET;
+
+static PRESET preset[] = {
+
+#ifdef CPU_OLD
+ { CPU_OLD, "1"},
+#endif
+#ifdef CPU_SP_OLD
+ { CPU_SP_OLD, "1"},
+#endif
+#ifdef SYSTEM_OLD
+ { SYSTEM_OLD, "1"},
+#endif
+#ifdef SYSTEM_SP_OLD
+ { SYSTEM_SP_OLD, "1"},
+#endif
+#ifdef COMPILER_OLD
+ { COMPILER_OLD, "1"},
+#endif
+#ifdef COMPILER_SP_OLD
+ { COMPILER_SP_OLD, "1"},
+#endif
+
+ { 0, 0}, /* End of macros beginning with alphabet */
+
+#ifdef CPU_STD
+ { CPU_STD, "1"},
+#endif
+#ifdef CPU_STD1
+ { CPU_STD1, "1"},
+#endif
+#ifdef CPU_STD2
+ { CPU_STD2, "1"},
+#endif
+#ifdef SYSTEM_STD
+ { SYSTEM_STD, "1"},
+#endif
+#ifdef SYSTEM_STD1
+ { SYSTEM_STD1, "1"},
+#endif
+#ifdef SYSTEM_STD2
+ { SYSTEM_STD2, "1"},
+#endif
+
+#ifdef SYSTEM_EXT
+ { SYSTEM_EXT, SYSTEM_EXT_VAL},
+#endif
+#ifdef SYSTEM_EXT2
+ { SYSTEM_EXT2, SYSTEM_EXT2_VAL},
+#endif
+#ifdef SYSTEM_SP_STD
+ { SYSTEM_SP_STD, SYSTEM_SP_STD_VAL},
+#endif
+#ifdef COMPILER_STD
+ { COMPILER_STD, COMPILER_STD_VAL},
+#endif
+#ifdef COMPILER_STD1
+ { COMPILER_STD1, COMPILER_STD1_VAL},
+#endif
+#ifdef COMPILER_STD2
+ { COMPILER_STD2, COMPILER_STD2_VAL},
+#endif
+#ifdef COMPILER_EXT
+ { COMPILER_EXT, COMPILER_EXT_VAL},
+#endif
+#ifdef COMPILER_EXT2
+ { COMPILER_EXT2, COMPILER_EXT2_VAL},
+#endif
+#ifdef COMPILER_SP_STD
+ { COMPILER_SP_STD, COMPILER_SP_STD_VAL},
+#endif
+#ifdef COMPILER_SP1
+ { COMPILER_SP1, COMPILER_SP1_VAL},
+#endif
+#ifdef COMPILER_SP2
+ { COMPILER_SP2, COMPILER_SP2_VAL},
+#endif
+#ifdef COMPILER_SP3
+ { COMPILER_SP3, COMPILER_SP3_VAL},
+#endif
+#ifdef COMPILER_SP4
+ { COMPILER_SP4, COMPILER_SP4_VAL},
+#endif
+#ifdef COMPILER_CPLUS
+ { COMPILER_CPLUS, COMPILER_CPLUS_VAL},
+#endif
+ { 0, 0}, /* End of macros with value of any integer */
+};
+
+static void init_defines( void)
+/*
+ * Initialize the built-in #define's.
+ * Called only on cpp startup prior to do_options().
+ *
+ * Note: the built-in static definitions are removed by the -N option,
+ * definitions beginning with alphabet are removed by the -S1 option,
+ */
+{
+ int n = sizeof preset / sizeof (PRESET);
+ PRESET * pp;
+
+ /* Predefine the built-in symbols. */
+ for (pp = preset; pp < preset + n; pp++) {
+ if (pp->name && *(pp->name))
+ look_and_install( pp->name, DEF_NOARGS - 1, null, pp->val);
+ }
+
+ look_and_install( "__MCPP", DEF_NOARGS - 1, null, "2");
+ /* MCPP V.2.x */
+ /* This macro is predefined yet can be undefined by -U or #undef. */
+}
+
+void un_predefine(
+ int clearall /* TRUE for -N option */
+)
+/*
+ * Remove predefined symbols from the symbol table.
+ */
+{
+ PRESET * pp;
+ DEFBUF * defp;
+ int n = sizeof preset / sizeof (PRESET);
+
+ for (pp = preset; pp < preset + n; pp++) {
+ if (pp->name) {
+ if (*(pp->name) && (defp = look_id( pp->name)) != 0
+ && defp->nargs == DEF_NOARGS - 1)
+ undefine( pp->name);
+ } else if (clearall == FALSE) { /* -S<n> option */
+ break;
+ }
+ }
+}
+
+void undef_a_predef(
+ const char * name
+)
+/*
+ * Remove a predefined name from the preset[] table so that the name can be
+ * redefined by -D option.
+ * The strange ordering (insert, command-line-scan, remove)
+ * is needed to avoid interaction with -D arguments.
+ */
+{
+ PRESET * pp;
+ int n = sizeof preset / sizeof (PRESET);
+
+ for (pp = preset; pp < preset + n; pp++) {
+ if (pp->name && *(pp->name) && str_eq( pp->name, name)) {
+ pp->name = "";
+ break;
+ }
+ }
+}
+
+/*
+ * output[] and out_ptr are used for:
+ * buffer to store preprocessed line (this line is put out or handed to
+ * post_preproc() via putout() in some cases)
+ */
+static char output[ NMACWORK]; /* Buffer for preprocessed line */
+static char * const out_end = & output[ NWORK - 2];
+ /* Limit of output line */
+static char * const out_wend = & output[ NMACWORK - 2];
+ /* Buffer end of output line */
+static char * out_ptr; /* Current pointer into output[]*/
+
+static void mcpp_main( void)
+/*
+ * Main process for mcpp -- copies tokens from the current input stream
+ * (main file or included file) to the output file.
+ */
+{
+ int c; /* Current character */
+ char * wp; /* Temporary pointer */
+ DEFBUF * defp; /* Macro definition */
+ int line_top; /* Is in the line top, possibly spaces */
+
+ if (! no_output) { /* Explicitly output a #line at the start of cpp */
+ src_line++;
+ sharp();
+ put_info(); /* -fworking-directory */
+ src_line--;
+ }
+ keep_comments = cflag && !no_output;
+
+ /*
+ * This loop is started "from the top" at the beginning of each line.
+ * 'wrong_line' is set TRUE in many places if it is necessary to write
+ * a #line record. (But we don't write them when expanding macros.)
+ *
+ * 'newlines' variable counts the number of blank lines that have been
+ * skipped over. These are then either output via #line records or
+ * by outputting explicit blank lines.
+ * 'newlines' will be cleared on end of an included file by get_ch().
+ */
+ while (1) { /* For the whole input */
+ newlines = 0; /* Count empty lines */
+
+ while (1) { /* For each line, ... */
+ out_ptr = output; /* Top of the line buf */
+ c = get_ch();
+ while (c == ' ' || c == '\t'
+ || (mcpp_mode == OLD_PREP && c == COM_SEP)) {
+ if (c == ' ' || c == '\t')
+ *out_ptr++ = c; /* Retain line top white spaces */
+ /* Else skip 0-length comment */
+ c = get_ch();
+ }
+ if (c == '#') { /* Is 1st non-space '#' */
+ directive(); /* Do a #directive */
+ } else if (mcpp_mode == STD && dig_flag && c == '%') {
+ /* In POST_STD digraphs are already converted */
+ if (get_ch() == ':') { /* '%:' i.e. '#' */
+ directive(); /* Do a #directive */
+ } else {
+ unget_ch();
+ if (! compiling) {
+ skip_nl();
+ newlines++;
+ } else {
+ break;
+ }
+ }
+ } else if (c == CHAR_EOF) { /* End of input */
+ break;
+ } else if (! compiling) { /* #ifdef false? */
+ skip_nl(); /* Skip to newline */
+ newlines++; /* Count it, too. */
+ } else if (in_asm && ! no_output) { /* In #asm block */
+ put_asm(); /* Put out as it is */
+ } else if (c == '\n') { /* Blank line */
+ if (keep_comments)
+ mcpp_fputc( '\n', OUT); /* May flush comments */
+ else
+ newlines++; /* Wait for a token */
+ } else {
+ break; /* Actual token */
+ }
+ }
+
+ if (c == CHAR_EOF) /* Exit process at */
+ break; /* end of input */
+
+ /*
+ * If the loop didn't terminate because of end of file, we
+ * know there is a token to compile. First, clean up after
+ * absorbing newlines. newlines has the number we skipped.
+ */
+ if (no_output) {
+ wrong_line = FALSE;
+ } else {
+ if (wrong_line || newlines > 10) {
+ sharp(); /* Output # line number */
+ } else { /* If just a few, stuff */
+ while (newlines-- > 0) /* them out ourselves */
+ mcpp_fputc('\n', OUT);
+ }
+ }
+
+ /*
+ * Process each token on this line.
+ */
+ line_top = TRUE;
+ while (c != '\n' && c != CHAR_EOF) { /* For the whole line */
+ if (scan_token( c, (wp = out_ptr, &wp), out_wend) == NAM
+ && (defp = is_macro( &wp)) != 0) { /* A macro */
+ wp = expand_macro( defp, out_ptr, out_wend);
+ /* Expand it completely */
+ if (line_top) { /* The first token is a macro */
+ char * tp = out_ptr;
+ while (*tp == ' ')
+ tp++; /* Remove excessive spaces */
+ ACE_OS::memmove( out_ptr, tp, ACE_OS::strlen( tp) + 1);
+ wp -= (tp - out_ptr);
+ }
+ if (has_pragma) { /* Found _Pramga() */
+ do_pragma_op(); /* Do _Pragma() operator*/
+ has_pragma = FALSE; /* Reset signal */
+ out_ptr = output; /* Do the rest of line */
+ wrong_line = TRUE; /* Line-num out of sync */
+ } else {
+ out_ptr = wp;
+ }
+ } else { /* Not a macro call */
+ out_ptr = wp; /* Advance the place */
+ if (wrong_line) /* is_macro() swallowed */
+ break; /* the newline */
+ }
+ if ((c = get_ch()) == ' ') { /* Token separator */
+ *out_ptr++ = ' ';
+ c = get_ch(); /* First of token */
+ }
+ if (mcpp_mode == OLD_PREP && c == COM_SEP)
+ c = get_ch(); /* Skip 0-length comment*/
+ line_top = FALSE; /* Read over some token */
+ } /* Loop for line */
+
+ putout( output); /* Output the line */
+ } /* Continue until EOF */
+}
+
+static void do_pragma_op( void)
+/*
+ * Execute the _Pragma() operator contained in an expanded macro.
+ * Note: _Pragma() operator is also implemented as a special macro. Therefore
+ * it is always searched as a macro.
+ * There might be more than one _Pragma() in a expanded macro and those may be
+ * surrounded by other token sequences.
+ * Since all the macros have been expanded completely, any name identical to
+ * macro should not be re-expanded.
+ */
+{
+ FILEINFO * file;
+ DEFBUF * defp;
+ int prev = output < out_ptr; /* There is a previous sequence */
+ int token_type;
+ char * cp1, * cp2;
+ int c;
+
+ file = unget_string( out_ptr, 0);
+ while (c = get_ch(), file == infile) {
+ if (c == ' ') {
+ *out_ptr++ = ' ';
+ continue;
+ }
+ if (scan_token( c, (cp1 = out_ptr, &cp1), out_wend)
+ == NAM && (defp = is_macro( &cp1)) != 0
+ && defp->nargs == DEF_PRAGMA) { /* _Pragma() operator */
+ if (prev) {
+ putout( output); /* Putout the previous sequence */
+ cp1 = stpcpy( output, "pragma "); /* From top of buffer */
+ }
+ *cp1++ = get_ch(); /* '(' */
+ while ((c = get_ch()) == ' ')
+ *cp1++ = ' ';
+ if (((token_type = scan_token( c, (cp2 = cp1, &cp1), out_wend))
+ != STR && token_type != WSTR)) {
+ /* Not a string literal */
+ put_seq( output, cp1);
+ return;
+ }
+ workp = de_stringize( cp2, work_buf);
+ while ((c = get_ch()) == ' ')
+ *cp1++ = ' ';
+ if (c != ')') { /* More than a string literal */
+ unget_ch();
+ put_seq( output, cp1);
+ return;
+ }
+ ACE_OS::strcpy( workp, "\n"); /* Terminate with <newline> */
+ unget_string( work_buf, 0);
+ do_pragma(); /* Do the #pragma "line" */
+ infile->bptr += ACE_OS::strlen( infile->bptr); /* Clear sequence */
+ cp1 = out_ptr = output; /* From the top of buffer */
+ prev = FALSE;
+ } else { /* Not pragma sequence */
+ out_ptr = cp1;
+ prev = TRUE;
+ }
+ }
+ unget_ch();
+ if (prev)
+ putout( output);
+}
+
+static void put_seq(
+ char * begin, /* Sequence already in buffer */
+ char * seq /* Sequence to be read */
+)
+/*
+ * Put out the failed sequence as it is.
+ */
+{
+ FILEINFO * file = infile;
+ int c;
+
+ cerror( "Operand of _Pragma() is not a string literal" /* _E_ */
+ , 0, 0L, 0);
+ while (c = get_ch(), file == infile)
+ *seq++ = c;
+ unget_ch();
+ out_ptr = seq;
+ putout( begin);
+}
+
+static char * de_stringize(
+ char * in, /* Null terminated string literal */
+ char * out /* Output buffer */
+)
+/*
+ * Make token sequence from a string literal for _Pragma() operator.
+ */
+{
+ char * in_p;
+ int c1;
+ int c;
+
+ in_p = in;
+ if (*in_p == 'L')
+ in_p++; /* Skip 'L' prefix */
+ while ((c = *++in_p) != EOS) {
+ if (c == '\\' && ((c1 = *(in_p + 1), c1 == '\\') || c1 == '"'))
+ c = *++in_p; /* "De-escape" escape sequence */
+ *out++ = c;
+ }
+ *--out = EOS; /* Remove the closing '"' */
+ return out;
+}
+
+static void putout(
+ char * out /* Output line (line-end is always 'out_ptr') */
+)
+/*
+ * Put out a line with or without "post-preprocessing".
+ */
+{
+ size_t len;
+
+ *out_ptr++ = '\n'; /* Put out a newline */
+ *out_ptr = EOS;
+
+#if ! MBCHAR_IS_ESCAPE_FREE
+ post_preproc( out);
+#elif ! HAVE_DIGRAPHS
+ if (mcpp_mode == STD && dig_flag)
+ post_preproc( out);
+#endif
+ /* Else no post-preprocess */
+ len = ACE_OS::strlen( out);
+ if (len > NWORK - 1)
+ devide_line( out);
+ else
+ put_a_line( out);
+}
+
+static void devide_line(
+ char * out /* 'out' is 'output' in actual */
+)
+/*
+ * Devide a too long line into output lines shorter than NWORK.
+ * This routine is called from putout().
+ */
+{
+ FILEINFO * file;
+ char * save;
+ char * wp;
+ int c;
+
+ file = unget_string( out, 0); /* To re-read the line */
+ wp = out_ptr = out;
+
+ while ((c = get_ch()), file == infile) {
+ if (c == ' ') {
+ if (out == out_ptr || *(out_ptr - 1) != ' ') {
+ *out_ptr++ = ' ';
+ wp++;
+ }
+ continue;
+ }
+ scan_token( c, &wp, out_wend); /* Read a token */
+ if (NWORK-2 < wp - out_ptr) { /* Too long a token */
+ cfatal( "Too long token %s", out_ptr, 0L, 0); /* _F_ */
+ } else if (out_end <= wp) { /* Too long line */
+ save = save_string( out_ptr); /* Save the token */
+ *out_ptr++ = '\n'; /* Append newline */
+ *out_ptr = EOS;
+ put_a_line( out); /* Putout the former tokens */
+ wp = out_ptr = stpcpy( out, save); /* Restore the token */
+ ACE_OS::free( save);
+ } else { /* Still in size */
+ out_ptr = wp; /* Advance the pointer */
+ }
+ }
+
+ unget_ch(); /* Push back the source character */
+ put_a_line( out); /* Putout the last tokens */
+ sharp(); /* Correct line number */
+}
+
+static void put_a_line(
+ char * out
+)
+/*
+ * Finally put out the preprocessed line.
+ */
+{
+ size_t len;
+ char * out_p;
+ char * tp;
+
+ if (no_output)
+ return;
+ len = ACE_OS::strlen( out);
+ tp = out_p = out + len - 2; /* Just before '\n' */
+ while (char_type[ *out_p & UCHARMAX] & SPA)
+ out_p--; /* Remove trailing white spaces */
+ if (out_p < tp) {
+ *++out_p = '\n';
+ *++out_p = EOS;
+ }
+
+ if (mcpp_fputs ( out, OUT) == EOF)
+ cfatal( "File write error", 0, 0L, 0); /* _F_ */
+}
+
+
+/*
+ * Routines to P O S T - P R E P R O C E S S
+ *
+ * 1998/08 created kmatsui (revised 1998/09, 2004/02, 2006/07)
+ * Supplementary phase for the older compiler-propers.
+ * 1. Convert digraphs to usual tokens.
+ * 2. Double '\\' of the second byte of multi-byte characters.
+ * These conversions are done selectively according to the macros defined
+ * in system.H.
+ * 1. Digraphs are converted if ! HAVE_DIGRAPHS and digraph recoginition
+ * is enabled by DIGRAPHS_INIT and/or -2 option on execution.
+ * 2. '\\' of the second byte of SJIS (BIGFIVE or ISO2022_JP) is doubled
+ * if bsl_need_escape == TRUE.
+ */
+
+#if HAVE_DIGRAPHS && MBCHAR_IS_ESCAPE_FREE
+ /* No post_preproc() */
+#else
+
+static int post_preproc(
+ char * out
+)
+/*
+ * Convert digraphs and double '\\' of the second byte of SJIS (BIGFIVE or
+ * ISO2022_JP).
+ */
+{
+#if ! HAVE_DIGRAPHS
+ int di_count = 0;
+#endif
+ int token_type;
+ int c;
+ char * str;
+ char * cp = out;
+
+ unget_string( out, 0);
+ while ((c = get_ch()) != '\n') { /* Not to read over to next line */
+ if (c == ' ') {
+ *cp++ = ' ';
+ continue;
+ }
+ str = cp;
+ token_type = scan_token( c, &cp, out_wend);
+ switch (token_type) {
+#if ! MBCHAR_IS_ESCAPE_FREE
+ case WSTR :
+ case WCHR :
+ str++; /* Skip prefix 'L' */
+ /* Fall through */
+ case STR :
+ case CHR :
+ if (bsl_need_escape)
+ cp = esc_mbchar( str, cp);
+ break;
+#endif /* ! MBCHAR_IS_ESCAPE_FREE */
+#if ! HAVE_DIGRAPHS
+ case OPE :
+ if (mcpp_mode == STD && (openum & OP_DIGRAPH)) {
+ cp = conv_a_digraph( cp); /* Convert a digraph */
+ di_count++;
+ }
+ break;
+#endif
+ }
+ }
+ *cp++ = '\n';
+ *cp = EOS;
+#if ! HAVE_DIGRAPHS
+ if (mcpp_mode == STD && di_count && (warn_level & 16))
+ cwarn( "%.0s%ld digraph(s) converted" /* _W16_ */
+ , 0, (long) di_count, 0);
+#endif
+ return 0;
+}
+
+#endif /* ! HAVE_DIGRAPHS || ! MBCHAR_IS_ESCAPE_FREE */
+
+#if ! HAVE_DIGRAPHS
+static char * conv_a_digraph(
+ char * cp /* The end of the digraph token */
+)
+/*
+ * Convert a digraph to usual token in place.
+ * This routine is never called in POST_STD mode.
+ */
+{
+ cp -= 2;
+ switch (openum) {
+ case OP_LBRACE_D :
+ *cp++ = '{';
+ break;
+ case OP_RBRACE_D :
+ *cp++ = '}';
+ break;
+ case OP_LBRCK_D :
+ *cp++ = '[';
+ break;
+ case OP_RBRCK_D :
+ *cp++ = ']';
+ break;
+ case OP_SHARP_D : /* Error of source */
+ *cp++ = '#';
+ break;
+ case OP_DSHARP_D : /* Error of source */
+ cp -= 2;
+ *cp++ = '#';
+ *cp++ = '#';
+ break;
+ }
+ return cp;
+}
+#endif /* ! HAVE_DIGRAPHS */
+
+#if ! MBCHAR_IS_ESCAPE_FREE
+static char * esc_mbchar(
+ char * str, /* String literal or character constant without 'L' */
+ char * str_end /* The end of the token */
+)
+/*
+ * Insert \ before the byte of 0x5c('\\') of the SJIS, BIGFIVE or ISO2022_JP
+ * multi-byte character code in string literal or character constant.
+ * Insert \ also before the byte of 0x22('"') and 0x27('\'') of ISO2022_JP.
+ * esc_mbchar() does in-place insertion.
+ */
+{
+ char * cp;
+ int delim;
+ int c;
+
+ if (! bsl_need_escape)
+ return str_end;
+ if ((delim = *str++) == 'L')
+ delim = *str++; /* The quote character */
+ while ((c = *str++ & UCHARMAX) != delim) {
+ if (char_type[ c] & mbstart) { /* MBCHAR */
+ cp = str;
+ mb_read( c, &str, (workp = work_buf, &workp));
+ while (cp++ < str) {
+ c = *(cp - 1);
+ if (c == '\\' || c == '"' || c == '\'') {
+ /* Insert \ before 0x5c, 0x22, 0x27 */
+ ACE_OS::memmove( cp, cp - 1, (size_t) (str_end - cp) + 2);
+ *(cp++ - 1) = '\\';
+ str++;
+ str_end++;
+ }
+ }
+ } else if (c == '\\' && ! (char_type[ *str & UCHARMAX] & mbstart)) {
+ str++; /* Escape sequence */
+ }
+ }
+ return str_end;
+}
+#endif /* ! MBCHAR_IS_ESCAPE_FREE */
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/mbchar.cpp b/TAO/TAO_IDL/contrib/mcpp/mbchar.cpp
new file mode 100644
index 00000000000..8f59ebe72e1
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/mbchar.cpp
@@ -0,0 +1,766 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * M B C H A R . C
+ * C h a r a c t e r h a n d l i n g R o u t i n e s
+ *
+ * Character handling and multi-byte character handling routines are
+ * placed here.
+ */
+
+#if PREPROCESSED
+#include "mcpp.H"
+#else
+#include "system.H"
+#include "internal.H"
+#endif
+
+/*
+ * Tables of character types and multi-byte character types.
+ * These tables must be rewritten for a non-Ascii machine.
+ *
+ * Some of these character attributes will be overwritten by
+ * execution time option '-@post' or '-@old'.
+ */
+
+#if DOLLAR_IN_NAME
+#define DOL LET
+#else
+#define DOL 000
+#endif
+
+short * char_type; /* Pointer to one of the following type_*[]. */
+
+#define EJ1 0x100 /* 1st byte of EUC_JP */
+#define EJ2 0x200 /* 2nd byte of EUC_JP */
+#define GB1 0x400 /* 1st byte of GB2312 */
+#define GB2 0x800 /* 2nd byte of GB2312 */
+#define KS1 0x1000 /* 1st byte of KSC5601 */
+#define KS2 0x2000 /* 2nd byte of KSC5601 */
+
+#define EJ12 (EJ1 | EJ2) /* 1st byte or 2nd byte of EUC_JP */
+#define GB12 (GB1 | GB2)
+#define KS12 (KS1 | KS2)
+#define EU12 (EJ12 | GB12 | KS12)
+ /* 1st or 2nd byte of EUC_JP, GB2312 or KSC5601 */
+
+static short type_euc[ UCHARMAX + 1] = {
+/*
+ * For EUC_JP, GB2312, KSC5601 or other similar multi-byte char encodings.
+ */
+
+/* Character type codes */
+/* 0, 1, 2, 3, 4, 5, 6, 7, */
+/* 8, 9, A, B, C, D, E, F, Hex */
+
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 00 */
+ 000, SPA, SPA, SPA, SPA, SPA, 000, 000, /* 08 */
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 10 */
+ /* 0x19, 0x1A and 0x1F will be cleared in some modes by chk_opts(). */
+ 000, LET, LET, 000, 000, 000, 000, SPA, /* 18 */
+ SPA, PUNC, QUO, PUNC, DOL, PUNC, PUNC, QUO, /* 20 !"#$%&' */
+ PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, DOT, PUNC, /* 28 ()*+,-./ */
+ DIG, DIG, DIG, DIG, DIG, DIG, DIG, DIG, /* 30 01234567 */
+ DIG, DIG, PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, /* 38 89:;<=>? */
+
+ 000, LET, LET, LET, LET, LET, LET, LET, /* 40 @ABCDEFG */
+ LET, LET, LET, LET, LET, LET, LET, LET, /* 48 HIJKLMNO */
+ LET, LET, LET, LET, LET, LET, LET, LET, /* 50 PQRSTUVW */
+ LET, LET, LET, PUNC, 000, PUNC, PUNC, LET, /* 58 XYZ[\]^_ */
+ 000, LET, LET, LET, LET, LET, LET, LET, /* 60 `abcdefg */
+ LET, LET, LET, LET, LET, LET, LET, LET, /* 68 hijklmno */
+ LET, LET, LET, LET, LET, LET, LET, LET, /* 70 pqrstuvw */
+ LET, LET, LET, PUNC, PUNC, PUNC, PUNC, 000, /* 78 xyz{|}~ */
+
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 80 .. 87 */
+ 000, 000, 000, 000, 000, 000, EJ1, 000, /* 88 .. 8F */
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 90 .. 97 */
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 98 .. 9F */
+ 000, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* A0 .. A7 */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* A8 .. AF */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* B0 .. B7 */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* B8 .. BF */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* C0 .. C7 */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* C8 .. CF */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* D0 .. D7 */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* D8 .. DF */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* E0 .. E7 */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* E8 .. EF */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, EU12, /* F0 .. F7 */
+ EU12, EU12, EU12, EU12, EU12, EU12, EU12, 000, /* F8 .. FF */
+};
+
+static short type_bsl[ UCHARMAX + 1] = {
+/*
+ * For SJIS, BIGFIVE or other similar encodings which may have '\\' value as
+ * the second byte of multi-byte character.
+ */
+
+#define SJ1 0x100 /* 1st byte of SJIS */
+#define SJ2 0x200 /* 2nd byte of SJIS */
+#define BF1 0x400 /* 1st byte of BIGFIVE */
+#define BF2 0x800 /* 2nd byte of BIGFIVE */
+
+#define SB2 (SJ2 | BF2)
+#define SJ12 (SJ1 | SJ2)
+#define BF12 (BF1 | BF2)
+#define SB12 (SJ12 | BF12)
+#define S2B12 (SJ2 | BF1 | BF2)
+
+#define LSB2 (LET | SB2)
+#define PSB2 (PUNC| SB2)
+
+/* Character type codes */
+/* 0, 1, 2, 3, 4, 5, 6, 7, */
+/* 8, 9, A, B, C, D, E, F, Hex */
+
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 00 */
+ 000, SPA, SPA, SPA, SPA, SPA, 000, 000, /* 08 */
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 10 */
+ /* 0x19, 0x1A and 0x1F will be cleared in some modes */
+ 000, LET, LET, 000, 000, 000, 000, SPA, /* 18 */
+ SPA, PUNC, QUO, PUNC, DOL, PUNC, PUNC, QUO, /* 20 !"#$%&' */
+ PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, DOT, PUNC, /* 28 ()*+,-./ */
+ DIG, DIG, DIG, DIG, DIG, DIG, DIG, DIG, /* 30 01234567 */
+ DIG, DIG, PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, /* 38 89:;<=>? */
+
+ SB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, /* 40 @ABCDEFG */
+ LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, /* 48 HIJKLMNO */
+ LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, /* 50 PQRSTUVW */
+ LSB2, LSB2, LSB2, PSB2, SB2, PSB2, PSB2, LSB2, /* 58 XYZ[\]^_ */
+ SB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, /* 60 `abcdefg */
+ LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, /* 68 hijklmno */
+ LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, LSB2, /* 70 pqrstuvw */
+ LSB2, LSB2, LSB2, PSB2, PSB2, PSB2, PSB2, 000, /* 78 xyz{|}~ */
+
+ SB2, SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, /* 80 .. 87 */
+ SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, /* 88 .. 8F */
+ SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, /* 90 .. 97 */
+ SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, SJ12, /* 98 .. 9F */
+ SJ2, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, /* A0 .. A7 */
+ S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, /* A8 .. AF */
+ S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, /* B0 .. B7 */
+ S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, /* B8 .. BF */
+ S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, /* C0 .. C7 */
+ S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, /* C8 .. CF */
+ S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, /* D0 .. D7 */
+ S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, S2B12, /* D8 .. DF */
+ SB12, SB12, SB12, SB12, SB12, SB12, SB12, SB12, /* E0 .. E7 */
+ SB12, SB12, SB12, SB12, SB12, SB12, SB12, SB12, /* E8 .. EF */
+ SB12, SB12, SB12, SB12, SB12, SB12, SB12, SB12, /* F0 .. F7 */
+ SB12, SB12, SB12, SB12, SB12, BF12, BF12, 000, /* F8 .. FF */
+};
+
+/*
+ * For ISO2022_JP multi-byte character encoding.
+ */
+
+#define IS1 0x40 /* 1st byte of shift-sequence */
+#define IS2 0x80 /* 2nd byte of shift-sequence */
+#define IS3 0x100 /* 3rd byte of shift-sequence */
+#define IS4 0x200 /* 4th byte of shift-sequence */
+#define IJP 0x400 /* 1st or 2nd byte of ISO-2022-JP (ISO-2022-JP1) */
+
+#define PIJP (PUNC | IJP)
+#define QIJP (QUO | IJP)
+#define DTJP (DOT | IJP)
+#define DGJP (DIG | IJP)
+#define LIJP (LET | IJP)
+
+#define DLJPS2 (DOL | IJP | IS2)
+#define PJPS23 (PIJP | IS2 | IS3)
+#define LJPS3 (LIJP | IS3)
+#define LJPS4 (LIJP | IS4)
+
+static short type_iso2022_jp[ UCHARMAX + 1] = {
+
+/* Character type codes */
+/* 0, 1, 2, 3, 4, 5, 6, 7, */
+/* 8, 9, A, B, C, D, E, F, Hex */
+
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 00 */
+ 000, SPA, SPA, SPA, SPA, SPA, 000, 000, /* 08 */
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 10 */
+ /* 0x19, 0x1A and 0x1F will be cleared in some modes */
+ 000, LET, LET, IS1, 000, 000, 000, SPA, /* 18 */
+ SPA, PIJP, QIJP, PIJP, DLJPS2,PIJP, PIJP, QIJP, /* 20 !"#$%&' */
+ PJPS23,PIJP, PIJP, PIJP, PIJP, PIJP, DTJP, PIJP, /* 28 ()*+,-./ */
+ DGJP, DGJP, DGJP, DGJP, DGJP, DGJP, DGJP, DGJP, /* 30 01234567 */
+ DGJP, DGJP, PIJP, PIJP, PIJP, PIJP, PIJP, PIJP, /* 38 89:;<=>? */
+
+ IJP, LIJP, LJPS3, LIJP, LJPS4, LIJP, LIJP, LIJP, /* 40 @ABCDEFG */
+ LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, /* 48 HIJKLMNO */
+ LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, /* 50 PQRSTUVW */
+ LIJP, LIJP, LIJP, PIJP, IJP, PIJP, PIJP, LIJP, /* 58 XYZ[\]^_ */
+ IJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, /* 60 `abcdefg */
+ LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, /* 68 hijklmno */
+ LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, LIJP, /* 70 pqrstuvw */
+ LIJP, LIJP, LIJP, PIJP, PIJP, PIJP, PIJP, 000, /* 78 xyz{|}~ */
+ /* the rests are 0 cleared */
+};
+
+/*
+ * For UTF8 multi-byte character encoding.
+ */
+
+#define U2_1 0x100 /* 1st byte of 2-byte encoding of UTF8 */
+#define U2_2 0x200 /* 2nd byte of 2-byte encoding of UTF8 */
+#define U3_1 0x400 /* 1st byte of 3-byte encoding of UTF8 */
+#define U3_2 0x800 /* 2nd byte of 3-byte encoding of UTF8 */
+#define U3_3 0x1000 /* 3rd byte of 3-byte encoding of UTF8 */
+
+#define UT23 (U2_2 | U3_3)
+/* 2nd byte of 2-byte encoding or 3rd byte of 3-byte encoding */
+#define UT223 (U2_2 | U3_2 | U3_3)
+/* 2nd byte of 2-byte encoding, or 2nd or 3rd byte of 3-byte encoding */
+
+static short type_utf8[ UCHARMAX + 1] = {
+
+/* Character type codes */
+/* 0, 1, 2, 3, 4, 5, 6, 7, */
+/* 8, 9, A, B, C, D, E, F, Hex */
+
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 00 */
+ 000, SPA, SPA, SPA, SPA, SPA, 000, 000, /* 08 */
+ 000, 000, 000, 000, 000, 000, 000, 000, /* 10 */
+ /* 0x19, 0x1A and 0x1F will be cleared in some modes */
+ 000, LET, LET, 000, 000, 000, 000, SPA, /* 18 */
+ SPA, PUNC, QUO, PUNC, DOL, PUNC, PUNC, QUO, /* 20 !"#$%&' */
+ PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, DOT, PUNC, /* 28 ()*+,-./ */
+ DIG, DIG, DIG, DIG, DIG, DIG, DIG, DIG, /* 30 01234567 */
+ DIG, DIG, PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, /* 38 89:;<=>? */
+
+ 000, LET, LET, LET, LET, LET, LET, LET, /* 40 @ABCDEFG */
+ LET, LET, LET, LET, LET, LET, LET, LET, /* 48 HIJKLMNO */
+ LET, LET, LET, LET, LET, LET, LET, LET, /* 50 PQRSTUVW */
+ LET, LET, LET, PUNC, 000, PUNC, PUNC, LET, /* 58 XYZ[\]^_ */
+ 000, LET, LET, LET, LET, LET, LET, LET, /* 60 `abcdefg */
+ LET, LET, LET, LET, LET, LET, LET, LET, /* 68 hijklmno */
+ LET, LET, LET, LET, LET, LET, LET, LET, /* 70 pqrstuvw */
+ LET, LET, LET, PUNC, PUNC, PUNC, PUNC, 000, /* 78 xyz{|}~ */
+
+ UT23, UT23, UT23, UT23, UT23, UT23, UT23, UT23, /* 80 .. 87 */
+ UT23, UT23, UT23, UT23, UT23, UT23, UT23, UT23, /* 88 .. 8F */
+ UT23, UT23, UT23, UT23, UT23, UT23, UT23, UT23, /* 90 .. 97 */
+ UT23, UT23, UT23, UT23, UT23, UT23, UT23, UT23, /* 98 .. 9F */
+ UT223, UT223, UT223, UT223, UT223, UT223, UT223, UT223, /* A0 .. A7 */
+ UT223, UT223, UT223, UT223, UT223, UT223, UT223, UT223, /* A8 .. AF */
+ UT223, UT223, UT223, UT223, UT223, UT223, UT223, UT223, /* B0 .. B7 */
+ UT223, UT223, UT223, UT223, UT223, UT223, UT223, UT223, /* B8 .. BF */
+ 000, 000, U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, /* C0 .. C7 */
+ U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, /* C8 .. CF */
+ U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, /* D0 .. D7 */
+ U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, U2_1, /* D8 .. DF */
+ U3_1, U3_1, U3_1, U3_1, U3_1, U3_1, U3_1, U3_1, /* E0 .. E7 */
+ U3_1, U3_1, U3_1, U3_1, U3_1, U3_1, U3_1, U3_1, /* E8 .. EF */
+ 000, 000, 000, 000, 000, 000, 000, 000, /* F0 .. F7 */
+ 000, 000, 000, 000, 000, 000, 000, 000, /* F8 .. FF */
+};
+
+#define SETLOCALE 2 /* #pragma setlocale (not __setlocale) */
+
+#define NUM_ENCODING 8
+#define NUM_ALIAS 7
+
+/*
+ * Names of encoding recognized. Table for search_encoding().
+ * Note: GCC documents that LANG=C-EUCJP (C-SJIS, C-JIS) is effective,
+ * though this feature is not fully enabled in GCC.
+ */
+static const char * const encoding_name[ NUM_ENCODING][ NUM_ALIAS] = {
+ /* normalized LANG, Visual C full, Visual C short
+ , miscellaneous */
+ { "c", "english", "c"
+ , "c", "en", "latin", "iso8859"},
+ { "ceucjp", "", ""
+ , "eucjp", "euc", "ujis", ""},
+ { "", "chinesesimplified", "chs"
+ , "gb2312", "cngb", "euccn", ""},
+ { "", "korean", "kor"
+ , "ksc5601", "ksx1001", "wansung", "euckr"},
+ { "csjis", "japanese", "jpn"
+ , "sjis", "shiftjis", "mskanji", ""},
+ { "", "chinesetraditional", "cht"
+ , "bigfive", "big5", "cnbig5", "euctw"},
+ { "cjis", "", ""
+ , "iso2022jp", "iso2022jp1", "jis", ""},
+ { "", "", ""
+ , "utf8", "utf", "", ""},
+};
+
+static int mb2;
+
+static size_t mb_read_2byte( int c1, char ** in_pp, char ** out_pp);
+ /* For 2-byte encodings of mbchar */
+static const char * search_encoding( char * norm, int alias);
+ /* Search encoding_name[][] table */
+static void strip_bar( char * string);
+ /* Remove '_', '-' or '.' in the string */
+static size_t mb_read_iso2022_jp( int c1, char ** in_pp, char ** out_pp);
+ /* For ISO2022_JP encoding */
+static size_t mb_read_utf8( int c1, char ** in_pp, char ** out_pp);
+ /* For UTF8 mbchar encoding */
+
+#define NAMLEN 20
+
+const char * set_encoding(
+ char * name, /* Name of encoding specified */
+ char * env, /* Name of environment variable */
+ int pragma
+ /* 2: #pragma setlocale, 1: #pragma __setlocale, 0: not #pragma */
+)
+/*
+ * Search the encoding specified and re-initialize mbchar settings.
+ */
+{
+ const char * unknown_encoding
+ = "Unknown encoding: %s%.0ld%.0s"; /* _W1_ */
+ const char * too_long
+ = "Too long encoding name: %s%.0ld%.0s"; /* _E_ */
+ const char * loc = "";
+ int alias;
+ char norm[ NAMLEN];
+ /*
+ * Normalized name (removed 'xxxxx.', stripped '_', '-', '.'
+ * and lowered.
+ */
+
+ if (ACE_OS::strlen( name) >= NAMLEN) {
+ if ((env || pragma) && (warn_level & 1)) {
+ cwarn( too_long, name, 0L, 0);
+ } else {
+ mcpp_fprintf( ERR, too_long, name);
+ mcpp_fputc( '\n', ERR);
+ }
+ }
+ ACE_OS::strcpy( norm, name);
+ if (norm[ 5] == '.')
+ ACE_OS::memmove( norm, norm + 5, ACE_OS::strlen( norm + 5) + 1);
+ /* Remove initial 'xxxxx.' as 'ja_JP.', 'en_US.' or any other */
+ conv_case( norm, norm + ACE_OS::strlen( norm), LOWER);
+ strip_bar( norm);
+
+ if (ACE_OS::strlen( name) == 0) { /* "" */
+ mbchar = MBCHAR; /* Restore to the default encoding */
+ } else if (ACE_OS::memcmp( norm, "iso8859", 7) == 0 /* iso8859* */
+ || ACE_OS::memcmp( norm, "latin", 5) == 0 /* latin* */
+ || ACE_OS::memcmp( norm, "en", 2) == 0) { /* en* */
+ mbchar = 0; /* No multi-byte character */
+ } else {
+ alias = 3;
+#if COMPILER == GNUC
+ if (env && str_eq( env, "LANG"))
+ alias = 0;
+#endif
+#if COMPILER == MSC
+ if (pragma == SETLOCALE) /* #pragma setlocale */
+ alias = 1;
+#endif
+ loc = search_encoding( norm, alias); /* Search the name */
+ }
+ if (loc == 0) {
+ if ((env || pragma) && (warn_level & 1)) {
+ cwarn( unknown_encoding, name, 0L, 0);
+ } else { /* -m option */
+ mcpp_fprintf( ERR, unknown_encoding, name);
+ mcpp_fputc( '\n', ERR);
+ }
+ } else {
+ mb_init(); /* Re-initialize */
+ }
+ return loc;
+}
+
+static const char * search_encoding(
+ char * norm, /* The name of encoding specified */
+ int alias /* The number of alias to start searching */
+)
+{
+ const char * loc;
+ int lo, al;
+
+ for (lo = 0; lo < NUM_ENCODING; lo++) {
+ for (al = alias ; al < NUM_ALIAS; al++) {
+ loc = encoding_name[ lo][ al];
+ if (str_eq( loc, norm)) {
+ switch (lo) {
+ case 0 : mbchar = 0; break;
+ case 1 : mbchar = EUC_JP; break;
+ case 2 : mbchar = GB2312; break;
+ case 3 : mbchar = KSC5601; break;
+ case 4 : mbchar = SJIS; break;
+ case 5 : mbchar = BIGFIVE; break;
+ case 6 : mbchar = ISO2022_JP; break;
+ case 7 : mbchar = UTF8; break;
+ }
+ return loc;
+ }
+#if COMPILER == GNUC
+ if (alias == 0 && al == 0) /* Searched the names for LANG */
+ al = 2; /* Skip the name for Visual C */
+#endif
+ }
+ }
+ return 0;
+}
+
+static void strip_bar(
+ char * string
+)
+/*
+ * Strip '_', '-' or '.' in the string.
+ */
+{
+ char * cp = string;
+
+ while (*cp != EOS) {
+ if (*cp == '_' || *cp == '-' || *cp == '.')
+ ACE_OS::memmove( cp, cp + 1, ACE_OS::strlen( cp));
+ else
+ cp++;
+ }
+}
+
+void mb_init( void)
+/*
+ * Initialize multi-byte character settings.
+ * First called prior to setting the 'mcpp_mode'.
+ * Will be called again each time the multibyte character encoding is changed.
+ */
+{
+ /*
+ * Select the character classification table, select the multi-byte
+ * character reading routine and decide whether multi-byte character
+ * may contain the byte of value 0x5c.
+ */
+ switch (mbchar) {
+ case 0 :
+ case EUC_JP :
+ case GB2312 :
+ case KSC5601 :
+ char_type = type_euc;
+ bsl_in_mbchar = FALSE;
+ mb_read = mb_read_2byte;
+ break;
+ case SJIS :
+ case BIGFIVE :
+ char_type = type_bsl;
+ bsl_in_mbchar = TRUE;
+ mb_read = mb_read_2byte;
+ break;
+ case ISO2022_JP :
+ char_type = type_iso2022_jp;
+ bsl_in_mbchar = TRUE;
+ mb_read = mb_read_iso2022_jp;
+ break;
+ case UTF8 :
+ char_type = type_utf8;
+ bsl_in_mbchar = FALSE;
+ mb_read = mb_read_utf8;
+ break;
+ }
+
+ /* Set the bit patterns for character classification. */
+ switch (mbchar) {
+ case 0 :
+ mbstart = 0;
+ mbmask = ~0;
+ break;
+ case EUC_JP :
+ mbstart = EJ1;
+ mbmask = ~EU12;
+ mb2 = EJ2;
+ break;
+ case GB2312 :
+ mbstart = GB1;
+ mbmask = ~EU12;
+ mb2 = GB2;
+ break;
+ case KSC5601:
+ mbstart = KS1;
+ mbmask = ~EU12;
+ mb2 = KS2;
+ break;
+ case SJIS :
+ mbstart = SJ1;
+ mbmask = ~SB12;
+ mb2 = SJ2;
+ break;
+ case BIGFIVE:
+ mbstart = BF1;
+ mbmask = ~SB12;
+ mb2 = BF2;
+ break;
+ case ISO2022_JP :
+ mbstart = IS1;
+ mbmask = ~(IS1 | IS2 | IS3 | IS4 | IJP);
+ break;
+ case UTF8 :
+ mbstart = (U2_1 | U3_1);
+ mbmask = ~(U2_1 | U2_2 | U3_1 | U3_2 | U3_3);
+ break;
+ }
+
+ /*
+ * Set special handling for some encodings to supplement some compiler's
+ * deficiency.
+ */
+ switch (mbchar) {
+ case SJIS :
+#if ! SJIS_IS_ESCAPE_FREE
+ bsl_need_escape = TRUE;
+#endif
+ break;
+ case BIGFIVE:
+#if ! BIGFIVE_IS_ESCAPE_FREE
+ bsl_need_escape = TRUE;
+#endif
+ break;
+ case ISO2022_JP :
+#if ! ISO2022_JP_IS_ESCAPE_FREE
+ bsl_need_escape = TRUE;
+#endif
+ break;
+ default :
+ bsl_need_escape = FALSE;
+ break;
+ }
+
+ /*
+ * Modify magic characters in character type table.
+ * char_type[] table should be rewritten in accordance with the 'mcpp_mode'
+ * whenever the encoding is changed.
+ */
+ if (mcpp_mode) { /* If mcpp_mode is already set */
+ char_type[ DEF_MAGIC] = standard ? LET : 0;
+ char_type[ IN_SRC] = (mcpp_mode == STD) ? LET : 0;
+ char_type[ TOK_SEP] = (mcpp_mode == STD || mcpp_mode == OLD_PREP)
+ ? SPA: 0; /* TOK_SEP equals to COM_SEP */
+ }
+}
+
+static size_t mb_read_2byte(
+ int , /* The 1st byte of mbchar sequence (already read) */
+ char ** in_pp, /* Pointer to input */
+ char ** out_pp /* Pointer to output */
+)
+/*
+ * Multi-byte character reading routine for 2-byte encodings.
+ */
+{
+ int error = FALSE;
+ size_t len = 0; /* Number of multi-byte characters read. */
+ char * in_p = *in_pp;
+ char * out_p = *out_pp;
+
+ do {
+ if (! (char_type[ (*out_p++ = *in_p++) & UCHARMAX] & mb2)) {
+ error = TRUE;
+ break;
+ }
+ len++;
+ } while (char_type[ (*out_p++ = *in_p++) & UCHARMAX] & mbstart);
+ *in_pp = --in_p;
+ *(--out_p) = EOS;
+ *out_pp = out_p;
+ return error ? (len | MB_ERROR) : len;
+}
+
+static size_t mb_read_iso2022_jp(
+ int c1, /* The 1st byte of the sequence already read (always 0x1b). */
+ char ** in_pp,
+ char ** out_pp
+)
+/*
+ * Multi-byte character reading routine for ISO2022_JP.
+ */
+{
+ int error = FALSE;
+ size_t len = 0;
+ char * in_p = *in_pp;
+ char * out_p = *out_pp;
+ int c2, c3, c4;
+
+ do {
+
+ *out_p++ = c2 = *in_p++;
+ if (! (char_type[ c2 & UCHARMAX] & IS2)) {
+ error = TRUE;
+ break;
+ }
+ *out_p++ = c3 = *in_p++;
+ if (! (char_type[ c3 & UCHARMAX] & IS3)) {
+ error = TRUE;
+ break;
+ }
+
+ switch (c2) {
+ case 0x24 :
+ switch (c3) {
+ case 0x42 : /* 0x1b 0x24 0x42: JIS X 0208-1983 */
+ break;
+ case 0x28 :
+ *out_p++ = c4 = *in_p++;
+ if (! (char_type[ c4 & UCHARMAX] & IS4))
+ error = TRUE;
+ /* else: 0x1b 0x24 0x28 0x44: JIS X 0212 */
+ break;
+ default :
+ error = TRUE;
+ }
+ break;
+ case 0x28 :
+ switch (c3) {
+ case 0x42 : /* 0x1b 0x28 0x42: ASCII */
+ c1 = *out_p++ = *in_p++ & UCHARMAX;
+ continue;
+ default :
+ error = TRUE;
+ }
+ break;
+ }
+ if (error)
+ break;
+
+ while (char_type[ c1 = *out_p++ = (*in_p++ & UCHARMAX)] & IJP) {
+ if (! (char_type[ *out_p++ = (*in_p++ & UCHARMAX)] & IJP)) {
+ error = TRUE;
+ break;
+ }
+ len++; /* String of multi-byte characters */
+ }
+ if (error)
+ break;
+
+ } while (char_type[ c1] & IS1); /* 0x1b: start of shift-sequence */
+
+ *in_pp = --in_p;
+ *(--out_p) = EOS;
+ *out_pp = out_p;
+ return error ? (len | MB_ERROR) : len;
+}
+
+static size_t mb_read_utf8(
+ int c1,
+ char ** in_pp,
+ char ** out_pp
+)
+/*
+ * Multi-byte character reading routine for UTF8.
+ */
+{
+ int error = FALSE;
+ size_t len = 0;
+ char * in_p = *in_pp;
+ char * out_p = *out_pp;
+ int c2;
+
+ do {
+ *out_p++ = c2 = *in_p++;
+ if (char_type[ c1 & UCHARMAX] & U2_1) { /* 2-byte character */
+ if (! (char_type[ c2 & UCHARMAX] & U2_2)) {
+ error = TRUE;
+ break;
+ }
+ } else {
+ if (char_type[ c2 & UCHARMAX] & U3_2) { /* 3-byte character */
+ if (! (char_type[ (*out_p++ = *in_p++) & UCHARMAX] & U3_3)) {
+ error = TRUE;
+ break;
+ }
+ } else {
+ error = TRUE;
+ break;
+ }
+ }
+ len++;
+ } while (char_type[ (*out_p++ = c1 = *in_p++) & UCHARMAX] & mbstart);
+ /* Start of the next multi-byte character */
+
+ *in_pp = --in_p;
+ *(--out_p) = EOS;
+ *out_pp = out_p;
+ return error ? (len | MB_ERROR) : len;
+}
+
+uexpr_t mb_eval(
+ char ** seq_pp
+)
+/*
+ * Evaluate the value of a multi-byte character.
+ * This routine does not check the legality of the sequence.
+ * This routine is called from eval_char().
+ * This routine is never called in POST_STD mode.
+ */
+{
+ char * seq = *seq_pp;
+ uexpr_t val = 0;
+ int c, c1;
+
+ switch (mbchar) {
+ case EUC_JP :
+ case GB2312 :
+ case KSC5601:
+ case SJIS :
+ case BIGFIVE:
+ val = (*seq++ & UCHARMAX) << 8;
+ val += *seq++ & UCHARMAX; /* Evaluate the 2-byte sequence */
+ break;
+ case ISO2022_JP :
+ if (char_type[ c = *seq++ & UCHARMAX] & IS1) {
+ /* Skip shift-sequence */
+ if (char_type[ c = *seq++ & UCHARMAX] & IS2) {
+ if (char_type[ c1 = *seq++ & UCHARMAX] & IS3) {
+ if (c1 == 0x28)
+ seq++;
+ if (c == 0x28 && c1 == 0x42) { /* Shift-out sequence */
+ val = 0;
+ break;
+ }
+ c = *seq++ & UCHARMAX;
+ }
+ }
+ }
+ val = (c << 8) + (*seq++ & UCHARMAX); /* Evaluate the 2-byte */
+ break;
+ case UTF8 : /* Evaluate the sequence of 2 or 3 bytes as it is */
+ if (char_type[ c = *seq++ & UCHARMAX] & U2_1) {
+ val = (c << 8) + (*seq++ & UCHARMAX);
+ } else {
+ val = (c << 8) + (*seq++ & UCHARMAX);
+ val = (val << 8) + (*seq++ & UCHARMAX);
+ }
+ break;
+ }
+
+ *seq_pp = seq;
+ return val;
+}
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/mcpp.mpc b/TAO/TAO_IDL/contrib/mcpp/mcpp.mpc
new file mode 100644
index 00000000000..cc6707f12a1
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/mcpp.mpc
@@ -0,0 +1,41 @@
+// $Id$
+project(tao_mcpp_exe) : aceexe, install, tao_output, crosscompile {
+ exename = tao_mcpp
+ requires += mcpp
+ Header_Files {
+ *.h
+ *.H
+ }
+
+ Source_Files {
+ directive.cpp
+ eval.cpp
+ expand.cpp
+ lib.cpp
+ main.cpp
+ mbchar.cpp
+ support.cpp
+ system.cpp
+ }
+}
+
+project(TAO_IDL_MCPP) : acelib, conv_lib, tao_output, crosscompile {
+ requires += mcpp
+ macros += MCPP_LIB
+
+ Header_Files {
+ *.h
+ *.H
+ }
+
+ Source_Files {
+ directive.cpp
+ eval.cpp
+ expand.cpp
+ lib.cpp
+ mcpp_lib.cpp
+ mbchar.cpp
+ support.cpp
+ system.cpp
+ }
+}
diff --git a/TAO/TAO_IDL/contrib/mcpp/mcpp_lib.cpp b/TAO/TAO_IDL/contrib/mcpp/mcpp_lib.cpp
new file mode 100644
index 00000000000..b89a09fba8d
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/mcpp_lib.cpp
@@ -0,0 +1,7 @@
+/** $Id$
+ * @file mcpp_lib.cpp
+ * Adapter to ensure the exe and/or lib compilations don't try to use the
+ * same .o file for main.cpp
+ */
+
+#include "main.cpp"
diff --git a/TAO/TAO_IDL/contrib/mcpp/mcpp_lib.h b/TAO/TAO_IDL/contrib/mcpp/mcpp_lib.h
new file mode 100644
index 00000000000..6664b44f889
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/mcpp_lib.h
@@ -0,0 +1,29 @@
+/* $Id$ */
+#ifndef MCPP_LIB_H
+#define MCPP_LIB_H
+
+#ifdef OUT
+#undef OUT
+#endif
+
+/* Choices for output destination */
+typedef enum {
+ OUT, /* ~= fp_out */
+ ERR, /* ~= fp_err */
+ DBG, /* ~= fp_debug */
+ NUM_OUTDEST
+} OUTDEST;
+
+#include "mcpp_lib_export.h"
+
+extern MCPP_LIB_Export int mcpp_lib_main( int argc, char ** argv);
+extern MCPP_LIB_Export void mcpp_reset_def_out_func( void);
+extern MCPP_LIB_Export void mcpp_set_out_func(
+ int (* func_fputc) ( int c, OUTDEST od),
+ int (* func_fputs) ( const char * s, OUTDEST od),
+ int (* func_fprintf)( OUTDEST od, const char * format, ...)
+ );
+extern MCPP_LIB_Export void mcpp_use_mem_buffers( int tf);
+extern MCPP_LIB_Export char * mcpp_get_mem_buffer( OUTDEST od);
+//#endif /* MCPP_LIB */
+#endif /* MCPP_LIB_H */
diff --git a/TAO/TAO_IDL/contrib/mcpp/mcpp_lib_export.h b/TAO/TAO_IDL/contrib/mcpp/mcpp_lib_export.h
new file mode 100644
index 00000000000..10df3543440
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/mcpp_lib_export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl MCPP_LIB
+// ------------------------------
+#ifndef MCPP_LIB_EXPORT_H
+#define MCPP_LIB_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (MCPP_LIB_HAS_DLL)
+# define MCPP_LIB_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && MCPP_LIB_HAS_DLL */
+
+#if !defined (MCPP_LIB_HAS_DLL)
+# define MCPP_LIB_HAS_DLL 1
+#endif /* ! MCPP_LIB_HAS_DLL */
+
+#if defined (MCPP_LIB_HAS_DLL) && (MCPP_LIB_HAS_DLL == 1)
+# if defined (MCPP_LIB_BUILD_DLL)
+# define MCPP_LIB_Export ACE_Proper_Export_Flag
+# define MCPP_LIB_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define MCPP_LIB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* MCPP_LIB_BUILD_DLL */
+# define MCPP_LIB_Export ACE_Proper_Import_Flag
+# define MCPP_LIB_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define MCPP_LIB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* MCPP_LIB_BUILD_DLL */
+#else /* MCPP_LIB_HAS_DLL == 1 */
+# define MCPP_LIB_Export
+# define MCPP_LIB_SINGLETON_DECLARATION(T)
+# define MCPP_LIB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* MCPP_LIB_HAS_DLL == 1 */
+
+// Set MCPP_LIB_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (MCPP_LIB_NTRACE)
+# if (ACE_NTRACE == 1)
+# define MCPP_LIB_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define MCPP_LIB_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !MCPP_LIB_NTRACE */
+
+#if (MCPP_LIB_NTRACE == 1)
+# define MCPP_LIB_TRACE(X)
+#else /* (MCPP_LIB_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define MCPP_LIB_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (MCPP_LIB_NTRACE == 1) */
+
+#endif /* MCPP_LIB_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/TAO_IDL/contrib/mcpp/noconfig.H b/TAO/TAO_IDL/contrib/mcpp/noconfig.H
new file mode 100644
index 00000000000..15623d3a62a
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/noconfig.H
@@ -0,0 +1,467 @@
+/* $Id$
+ * noconfig.H
+ * Configurations for MCPP not using config.h.
+ *
+ * WARNING: These are default settings. To configure for your system, you
+ * must edit this file here and there.
+ */
+
+#define TRUE 1
+#define FALSE 0
+
+/*
+ * 'Target' means the O.S. and the compiler to which cpp is implemented.
+ * 'Host' means the O.S. and the compiler with which cpp is compiled.
+ */
+
+/* Define target operating-system. */
+#define SYSTEM SYS_FREEBSD
+
+/* Define target compiler. */
+#ifndef COMPILER
+#define COMPILER INDEPENDENT /* compiler-independent-build */
+#endif
+
+/* Define host operating-system. */
+#define HOST_SYSTEM SYSTEM
+
+/* Define host compiler. */
+#define HOST_COMPILER GNUC
+
+/* Version message. */
+/* "MCPP V.2.* (200y/mm) compiled by " precedes VERSION_MSG */
+#define VERSION_MSG "GCC 3.4"
+#if 0
+ "LCC-Win32 2006-03"
+ "Visual C 2005"
+ "Visual C 2003"
+ "BCC V.5.5"
+#endif
+
+/*
+ * P A R T 1 Configurations for target-operating-system
+ * and target-compiler.
+ */
+
+/*
+ * Names of the SYSTEM (i.e. target operating system). This is needed so that
+ * cpp can use appropriate filename conventions.
+ */
+#define SYS_UNKNOWN 0
+#define SYS_UNIX 0x1000
+#define SYS_LINUX 0x1800 /* (SYS_LINUX & 0xF000) == SYS_UNIX */
+#define SYS_FREEBSD 0x1A00 /* (SYS_FREEBSD & 0xF000) == SYS_UNIX */
+#define SYS_CYGWIN 0x1C00 /* (SYS_CYGWIN & 0xF000) == SYS_UNIX */
+#define SYS_MAC 0x6000
+#define SYS_WIN 0x7000
+#define SYS_WIN32 0x7400 /* (SYS_WIN32 & 0xF000) == SYS_WIN */
+#define SYS_MINGW 0x7C00 /* (SYS_MINGW & 0xF000) == SYS_WIN */
+
+/* COMPILER */
+#define COMPILER_UNKNOWN 0
+#define MSC 0x7400 /* Microsoft C, Visual C++ */
+#define BORLANDC 0x7440 /* Borland C */
+#define WIN_SYMANTECC 0x7470 /* Symantec for Windows */
+#define LCC 0x74C0 /* LCC-Win32 */
+#define GNUC 0x00E0 /* GNU C (GCC) */
+#define INDEPENDENT 0xFFFF /* No target, compiler-independent build*/
+
+#define SYS_FAMILY (SYSTEM & 0xF000)
+#define COMPILER_FAMILY (COMPILER & 0xF0)
+#define HOST_SYS_FAMILY (HOST_SYSTEM & 0xF000)
+
+/* Default MBCHAR (multi-byte character) encoding. */
+#define EUC_JP 0x10 /* Extended UNIX code of JIS X 0208 */
+#define GB2312 0x20 /* EUC-like encoding of Chinese GB 2312-80 */
+#define KSC5601 0x30 /* EUC-like encoding of Korean KS C 5601 */
+#define SJIS 0x80 /* Shift-JIS encoding of JIS X 0208 */
+#define BIGFIVE 0x90 /* Encoding of Taiwanese Big Five */
+#define ISO2022_JP 0x100 /* ISO-2022-JP (ISO-2022-JP1) encoding */
+#define UTF8 0x1000 /* UTF-8 encoding */
+
+/*
+ * MBCHAR means multi-byte character encoding.
+ * MBCHAR means the default encoding, and you can change the encoding by
+ * #pragma MCPP setlocale, -e <encoding> option or environment variable
+ * LC_ALL, LC_CTYPE, LANG.
+ * MBCHAR == 0 means no multi-byte character encoding.
+ */
+
+/*
+ * In order to predefine target-system-dependent macros,
+ * several macros are defined here:
+ * *_OLD define the macro beginning with an alphabetic letter,
+ * *_STD, *_STD?, *_EXT, *_EXT2 define the macro beginning with an '_'.
+ * *_STD1 define the macro beginning with '__' and ending with an alpha-
+ * numeric letter.
+ * *_STD2 define the macro beginning with '__' and ending with '__'.
+ * These may not be defined, if they are not needed.
+ * They should not be #defined to no token or to "".
+ *
+ * CPU_OLD, CPU_STD1, CPU_STD2, CPU_SP_OLD, CPU_SP_STD
+ * define the target cpu (by name)
+ * SYSTEM_OLD, SYSTEM_STD1, SYSTEM_STD2, SYSTEM_EXT, SYSTEM_EXT2
+ * define the target operating system (by name)
+ * SYSTEM_SP_OLD, SYSTEM_SP_STD define the target-OS specific macro name
+ * COMPILER_OLD, COMPILER_STD1, COMPILER_STD2, COMPILER_EXT, COMPILER_EXT2
+ * , COMPILER_SP_OLD, COMPILER_SP_STD
+ * define the target compiler (by name)
+ * COMPILER_CPLUS define the target C++ compiler
+ * COMPILER_SP1, COMPILER_SP2, COMPILER_SP3, COMPILER_SP4
+ * define the compiler-specific macros
+ *
+ * <macro>_VAL specify the value of the <macro>.
+ * If not specified, these values default to "1".
+ * To define the value of no-token, specify as "" rather than no-token.
+ * CPU_*, SYSTEM_OLD, SYSTEM_STD?, COMPILER_OLD have the value of "1".
+ */
+
+/*
+ * target-compiler-dependent definitions:
+ *
+ * LINE_PREFIX defines the output line prefix, if not "#line 123".
+ * This should be defined as "# " to represent "# 123" format
+ * ("#line " represents "#line 123" format).
+ *
+ * C_INCLUDE_DIR1, C_INCLUDE_DIR2 may be defined if you have a compiler-
+ * specific include directory which is to be searched *before*
+ * the operating-system specific directories (e.g. /usr/include).
+ * CPLUS_INCLUDE_DIR1, CPLUS_INCLUDE_DIR2, CPLUS_INCLUDE_DIR3
+ * , CPLUS_INCLUDE_DIR4 are for C++ include directory which exist
+ * other than C include directory.
+ * ENV_C_INCLUDE_DIR may be defined to the name of environment-variable for
+ * C include directory.
+ * ENV_CPLUS_INCLUDE_DIR is name of environment-variable for C++ include
+ * directory which exists other than ENV_C_INCLUDE_DIR.
+ * ENV_SEP is the separator (other than space) of include-paths in an
+ * environment-variable. e.g. the ':' in
+ * "/usr/abc/include:/usr/xyz/include"
+ *
+ * EMFILE should be defined to the macro to represent errno of 'too many
+ * open files' if the macro is different from EMFILE.
+ *
+ * ONE_PASS should be set TRUE, if COMPILER is "one pass compiler".
+ *
+ * FNAME_FOLD means that target-system folds upper and lower cases of
+ * directory and file-name.
+ *
+ * SEARCH_INIT specifies the default value of 'search_rule' (in system.c).
+ * 'search_rule' holds searching rule of #include "header.h" to
+ * search first before searching user specified or system-
+ * specific include directories.
+ * CURRENT means to search the directory relative to "current
+ * directory" which is current at cpp invocation.
+ * SOURCE means to search the directory relative to that of the
+ * source file (i.e. "includer").
+ * (CURRENT & SOURCE) means to search current directory first
+ * source directory next.
+ * 'search_rule' is initialized to SEARCH_INIT.
+ */
+#define CURRENT 1
+#define SOURCE 2
+
+#if SYS_FAMILY == SYS_UNIX
+#define SYSTEM_OLD "unix"
+#define SYSTEM_STD1 "__unix"
+#define SYSTEM_STD2 "__unix__"
+#endif
+
+#if SYSTEM == SYS_FREEBSD || SYSTEM == SYS_LINUX
+#define CPU_STD2 "__i386__"
+#endif
+
+#if SYSTEM == SYS_FREEBSD
+#define SYSTEM_EXT "__FreeBSD__"
+#define SYSTEM_EXT_VAL "6" /* V.5.*: 5, V.6.*:6 */
+#endif
+
+#if SYSTEM == SYS_LINUX
+#define SYSTEM_EXT "__linux__"
+#endif
+
+#if SYSTEM == SYS_CYGWIN
+#define CPU_STD2 "__i386__"
+#define SYSTEM_EXT "__CYGWIN__"
+#define SYSTEM_EXT2 "__CYGWIN32__"
+#define MBCHAR SJIS
+#define FNAME_FOLD TRUE
+#define CYGWIN_ROOT_DIRECTORY "c:/pub/compilers/cygwin"
+#endif /* SYSTEM == SYS_CYGWIN */
+
+#if SYSTEM == SYS_MINGW
+#define SYSTEM_EXT "__MINGW__"
+#define SYSTEM_EXT2 "__MINGW32__"
+#define MSYS_ROOT_DIRECTORY "c:/pub/compilers/msys/1.0"
+#define MINGW_DIRECTORY "c:/pub/compilers/mingw"
+#if COMPILER == GNUC
+#define SJIS_IS_ESCAPE_FREE FALSE
+#endif
+#endif /* SYSTEM == SYS_MINGW */
+
+#if SYS_FAMILY == SYS_UNIX
+#ifndef MBCHAR
+#define MBCHAR EUC_JP /* UTF8 if you like */
+#endif
+#ifndef FNAME_FOLD
+#define FNAME_FOLD FALSE
+#endif
+#endif
+
+
+#if COMPILER == INDEPENDENT
+/* specifications of compiler-independent build */
+#define LINE_PREFIX "#line "
+#define STD_LINE_PREFIX TRUE /* Output #line by C source format */
+#define HAVE_DIGRAPHS TRUE /* Output digraphs as it is */
+#define SEARCH_INIT SOURCE /* Include directory relative to source */
+#define SJIS_IS_ESCAPE_FREE TRUE /* Do not treat SJIS specially */
+#define BIGFIVE_IS_ESCAPE_FREE TRUE /* Do not treat specially */
+#define ISO2022_JP_IS_ESCAPE_FREE TRUE /* Do not treat specially */
+#define TARGET_HAVE_LONG_LONG TRUE /* dummy */
+#define STDC_VERSION 199409L /* Initial value of __STDC_VERSION__ */
+#endif
+
+/*
+ * defaults
+ */
+
+#ifdef SYSTEM_EXT
+#ifndef SYSTEM_EXT_VAL
+#define SYSTEM_EXT_VAL "1"
+#endif
+#endif
+#ifdef SYSTEM_EXT2
+#ifndef SYSTEM_EXT2_VAL
+#define SYSTEM_EXT2_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_STD1
+#ifndef COMPILER_STD1_VAL
+#define COMPILER_STD1_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_STD2
+#ifndef COMPILER_STD2_VAL
+#define COMPILER_STD2_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_EXT
+#ifndef COMPILER_EXT_VAL
+#define COMPILER_EXT_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_EXT2
+#ifndef COMPILER_EXT2_VAL
+#define COMPILER_EXT2_VAL "1"
+#endif
+#endif
+#ifdef COMPILER_CPLUS
+#ifndef COMPILER_CPLUS_VAL
+#define COMPILER_CPLUS_VAL "1"
+#endif
+#endif
+
+#ifndef LINE_PREFIX
+#define LINE_PREFIX "#line "
+#define STD_LINE_PREFIX TRUE /* C source format */
+#else
+#ifndef STD_LINE_PREFIX
+#define STD_LINE_PREFIX FALSE /* Compiler-dependent format */
+#endif
+#endif
+
+#ifndef HAVE_DIGRAPHS
+#define HAVE_DIGRAPHS FALSE
+#endif
+
+#ifndef ENV_C_INCLUDE_DIR
+#define ENV_C_INCLUDE_DIR "INCLUDE"
+#endif
+#ifndef ENV_CPLUS_INCLUDE_DIR
+#define ENV_CPLUS_INCLUDE_DIR "CPLUS_INCLUDE"
+#endif
+
+#ifndef ENV_SEP
+#if SYS_FAMILY == SYS_WIN
+#define ENV_SEP ';'
+#else
+#define ENV_SEP ':'
+#endif
+#endif
+
+#ifndef ONE_PASS
+#define ONE_PASS FALSE
+#endif
+
+#ifndef FNAME_FOLD
+#define FNAME_FOLD TRUE
+#endif
+
+#ifndef SEARCH_INIT
+#define SEARCH_INIT CURRENT
+#endif
+
+/*
+ * CHARBIT, UCHARMAX are respectively CHAR_BIT, UCHAR_MAX of target compiler.
+ * CHARBIT should be defined to the number of bits per character.
+ * It is needed only for processing of multi-byte character constants.
+ * UCHARMAX should be defined to the maximum value of type unsigned char
+ * or maximum value of unsigned int which is converted from type (signed)
+ * char.
+ *
+ * LONGMAX should be defined to the LONG_MAX in <limits.h>.
+ * ULONGMAX should be defined to the ULONG_MAX in <limits.h> or LONG_MAX
+ * for the compiler which lacks of unsigned long.
+ */
+
+#ifndef CHARBIT
+#define CHARBIT 8
+#endif
+#ifndef UCHARMAX
+#define UCHARMAX 0xFF
+#endif
+#ifndef LONGMAX
+#define LONGMAX 0x7FFFFFFFL
+#endif
+#ifndef ULONGMAX
+#define ULONGMAX 0xFFFFFFFFUL
+#endif
+
+/*
+ * Define MBCHAR (multi-byte character encoding) to SJIS, EUC_JP or other.
+ */
+#ifndef MBCHAR
+#define MBCHAR 0
+#endif
+
+/*
+ * SJIS_IS_ESCAPE_FREE means the compiler does not escape '0x5c' ('\\') in
+ * shift-JIS encoded multi-byte character. SJIS_IS_ESCAPE_FREE == FALSE
+ * enables cpp to insert * '\\' before '\\' of the 2nd byte of SJIS code in
+ * literal. This insertion is for the compiler-proper which can't recognize
+ * SJIS literal.
+ * BIGFIVE_IS_ESCAPE_FREE means similar case on BIGFIVE encoding.
+ * ISO2022_JP_IS_ESCAPE_FREE means similar case on ISO2022_JP encoding.
+ *
+ * GCC can handle these encodings if it has been configured so.
+ */
+#ifndef SJIS_IS_ESCAPE_FREE
+#define SJIS_IS_ESCAPE_FREE FALSE /* or TRUE following your compiler */
+#endif
+#ifndef BIGFIVE_IS_ESCAPE_FREE
+#define BIGFIVE_IS_ESCAPE_FREE FALSE /* or TRUE following your compiler */
+#endif
+#ifndef ISO2022_JP_IS_ESCAPE_FREE
+#define ISO2022_JP_IS_ESCAPE_FREE FALSE /* or TRUE following compiler */
+#endif
+
+/*
+ * P A R T 2 Configurations for host-compiler.
+ *
+ * WARNING: In case of HOST_COMPILER differs from COMPILER, you must
+ * edit here and there of this part.
+ */
+#if HOST_COMPILER == GNUC
+#if __GNUC__ >= 3
+#define HAVE_INTMAX_T TRUE
+#define HAVE_INTTYPES_H TRUE
+#endif
+#define HOST_HAVE_LONG_LONG TRUE
+#define HOST_HAVE_GETOPT TRUE
+#if HOST_SYSTEM == SYS_LINUX
+#define HOST_HAVE_STPCPY TRUE
+#define HOST_LIB_IS_GLIBC TRUE
+#endif
+
+#elif HOST_COMPILER == LCC
+#define HOST_HAVE_LONG_LONG TRUE
+
+#elif HOST_COMPILER == MSC
+#define HOST_HAVE_LONG_LONG TRUE
+
+#elif HOST_COMPILER == BORLANDC
+#if __BORLANDC__ >= 0x550
+#define HOST_HAVE_LONG_LONG TRUE
+#endif
+#define HOST_HAVE_STPCPY TRUE
+#endif
+
+#ifndef HAVE_INTMAX_T
+#define HAVE_INTMAX_T FALSE
+#endif
+
+/* The host compilers both have the type long long int ? */
+#ifndef HOST_HAVE_LONG_LONG
+#define HOST_HAVE_LONG_LONG FALSE
+#endif
+
+/*
+ * This definitions should be set TRUE, if *both* of the target
+ * and the host compilers have long long type.
+ */
+#if TARGET_HAVE_LONG_LONG && HOST_HAVE_LONG_LONG
+#define HAVE_LONG_LONG TRUE
+#endif
+
+/*
+ * Define the format specifier of intmax_t or long long for
+ * fprintf( fp_debug,).
+ * Both of target COMPILER and HOST_COMPILER should have long long.
+ */
+#if HAVE_LONG_LONG
+#if HOST_COMPILER == BORLANDC \
+ || (HOST_COMPILER == MSC && _MSC_VER < 1400) \
+ || HOST_SYSTEM == SYS_MINGW
+#define LL_FORM "I64" /* Format specifier for __int64 */
+#endif
+#ifndef LL_FORM
+#define LL_FORM "ll" /* C99: for long long, "j" for intmax_t */
+#endif
+#endif
+
+#ifndef HOST_HAVE_STPCPY
+#define HOST_HAVE_STPCPY FALSE
+#endif
+#ifndef HOST_HAVE_GETOPT
+#define HOST_HAVE_GETOPT FALSE
+#endif
+#ifndef HOST_LIB_IS_GLIBC
+#define HOST_LIB_IS_GLIBC FALSE
+#endif
+
+/*
+ * Declaration of standard library functions and macros.
+ */
+
+/* stdin, stdout, stderr, FILE, NULL, fgets(), fputs() and other functions. */
+#include "stdio.h"
+
+/* FILENAMEMAX should be defined to FILENAME_MAX of host system. */
+#ifdef FILENAME_MAX
+#define FILENAMEMAX FILENAME_MAX
+#else
+#define FILENAMEMAX BUFSIZ
+#endif
+
+/* islower(), isupper(), toupper(), isdigit(), isxdigit(), iscntrl() */
+#include "ctype.h"
+
+/* errno */
+#include "errno.h"
+
+#include "string.h"
+#include "stdlib.h"
+#include "time.h"
+#include "setjmp.h"
+
+
+#define NEED_GETOPT TRUE
+
+
+extern char * stpcpy( char * dest, const char * src);
+
+/* For debugging malloc systems by kmatsui */
+#if KMMALLOC && _MEM_DEBUG
+#include "xalloc.h"
+#endif
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/preproc.cpp b/TAO/TAO_IDL/contrib/mcpp/preproc.cpp
new file mode 100644
index 00000000000..006488b9cdd
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/preproc.cpp
@@ -0,0 +1,9 @@
+/* $Id$ preproc.c: to "pre-preprocess" header files. */
+
+#pragma MCPP preprocess
+
+#include "system.H"
+#include "internal.H"
+
+#pragma MCPP put_defines
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/support.cpp b/TAO/TAO_IDL/contrib/mcpp/support.cpp
new file mode 100644
index 00000000000..44a8760df32
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/support.cpp
@@ -0,0 +1,2577 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * S U P P O R T . C
+ * S u p p o r t R o u t i n e s
+ *
+ * The common routines used by several source files are placed here.
+ */
+
+/*
+ * The following are global functions.
+ *
+ * get_unexpandable() Gets the next unexpandable token in the line, expanding
+ * macros.
+ * Called from #if, #line and #include processing routines.
+ * skip_nl() Skips over a line.
+ * skip_ws() Skips over white spaces but not skip over the end of the line.
+ * skip_ws() skips also COM_SEP and TOK_SEP.
+ * scan_token() Reads the next token of any type into the specified output
+ * pointer, advances the pointer, returns the type of token.
+ * scan_quote() Reads a string literal, character constant or header-name from
+ * the input stream, writes out to the specified buffer and
+ * returns the advanced output pointer.
+ * get_ch() Reads the next byte from the current input stream, handling
+ * end of (macro/file) input and embedded comments appropriately.
+ * cnv_trigraph() Maps trigraph sequence to C character.
+ * cnv_digraph() Maps digraph sequence to C character.
+ * id_operator() See whether the identifier is an operator in C++.
+ * unget_ch() Pushs last gotten character back on the input stream.
+ * unget_string() Pushs sequence on the input stream.
+ * save_string() Saves a string in malloc() memory.
+ * get_file() Initializes a new FILEINFO structure, called when #include
+ * opens a new file.
+ * xmalloc() Gets a specified number of bytes from heap memory.
+ * If malloc() returns NULL, exits with a message.
+ * xrealloc() realloc(). If it fails, exits with a message.
+ * cfatal(), cerror(), cwarn()
+ * These routines format print messages to the user.
+ * mcpp_fputc(), mcpp_fputs(), mcpp_fprintf()
+ * Wrap library functions to support alternate output to memory
+ * buffer.
+ */
+
+#if PREPROCESSED
+#include "mcpp.H"
+#else
+#include "system.H"
+#include "internal.H"
+#endif
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/OS_NS_stdlib.h"
+
+static void scan_id( int c);
+ /* Scan an identifier */
+static char * scan_number( int c, char * out, char * out_end);
+ /* Scan a preprocessing number */
+static char * scan_number_prestd( int c, char * out, char * out_end);
+ /* scan_number() for pre-Standard */
+#if OK_UCN
+static char * scan_ucn( int cnt, char * out);
+ /* Scan an UCN sequence */
+#endif
+static char * scan_op( int c, char * out);
+ /* Scan an operator or punctuat.*/
+static char * parse_line( void);
+ /* Parse a logical line */
+static char * read_a_comment( char * sp);
+ /* Read over a comment */
+static char * get_line( int in_comment);
+ /* Get a logical line from file */
+static void at_eof( int in_comment);
+ /* Check erroneous end of file */
+static void do_msg( const char * severity, const char * format
+ , const char * arg1, long arg2, const char * arg3);
+ /* Putout diagnostic message */
+static char * cat_line( int del_bsl);
+ /* Splice the line */
+static int last_is_mbchar( const char * in, int len);
+ /* The line ends with MBCHAR ? */
+static void put_line( char * out, FILE * fp);
+ /* Put out a logical line */
+static void dump_token( int token_type, const char * cp);
+ /* Dump a token and its type */
+
+#define EXP_MAC_IND_MAX 16
+/* Information of current expanding macros for diagnostic */
+typedef struct expanding_mac {
+ const char * name; /* Name of the macro just expanded */
+ int to_be_freed; /* Name should be freed later */
+} EXPANDING_MAC;
+static EXPANDING_MAC expanding_macro[ EXP_MAC_IND_MAX];
+static int exp_mac_ind = 0; /* Index into expanding_macro[] */
+
+static int in_token = FALSE; /* For token scanning functions */
+static int in_string = FALSE; /* For get_ch() and parse_line()*/
+static int squeezews = FALSE;
+
+#if MCPP_LIB
+static int use_mem_buffers = FALSE;
+
+void init_support( void)
+{
+ in_token = in_string = squeezews = FALSE;
+ clear_exp_mac();
+}
+
+typedef struct mem_buf {
+ char * buffer;
+ char * entry_pt;
+ size_t size;
+ size_t bytes_avail;
+} MEMBUF;
+
+static MEMBUF mem_buffers[ NUM_OUTDEST];
+
+void mcpp_use_mem_buffers(
+ int tf
+)
+{
+ use_mem_buffers = tf ? TRUE : FALSE;
+
+ if (use_mem_buffers) {
+ int i;
+
+ for (i = 0; i < NUM_OUTDEST; ++i) {
+ if (mem_buffers[ i].buffer) /* Already allocated */
+ ACE_OS::free( mem_buffers[ i].buffer);
+ mem_buffers[ i].buffer = 0;
+ mem_buffers[ i].entry_pt = 0;
+ mem_buffers[ i].size = 0;
+ mem_buffers[ i].bytes_avail = 0;
+ }
+ }
+}
+
+int using_mem_buffers( void)
+{
+ return use_mem_buffers;
+}
+
+#define BUF_INCR_SIZE (NWORK * 2)
+#ifdef MAX
+#undef MAX
+#endif
+#define MAX( a, b) (((a) > (b)) ? (a) : (b))
+
+static char * append_to_buffer(
+ MEMBUF * mem_buf_p,
+ const char * string,
+ size_t length
+)
+{
+ if (mem_buf_p->bytes_avail < length) { /* Need to allocate more memory */
+ size_t size = MAX( BUF_INCR_SIZE, length);
+
+ if (mem_buf_p->buffer == 0) { /* 1st append */
+ mem_buf_p->size = size;
+ mem_buf_p->bytes_avail = size;
+ mem_buf_p->buffer = xmalloc( mem_buf_p->size);
+ mem_buf_p->entry_pt = mem_buf_p->buffer;
+ } else {
+ mem_buf_p->size += size;
+ mem_buf_p->bytes_avail += size;
+ mem_buf_p->buffer = xrealloc( mem_buf_p->buffer, mem_buf_p->size);
+ mem_buf_p->entry_pt = mem_buf_p->buffer + mem_buf_p->size
+ - mem_buf_p->bytes_avail;
+ }
+ }
+
+ /* Append the string to the tail of the buffer */
+ ACE_OS::memcpy( mem_buf_p->entry_pt, string, length);
+ mem_buf_p->entry_pt += length;
+ mem_buf_p->entry_pt[ 0] = '\0'; /* Terminate the string buffer */
+ mem_buf_p->bytes_avail -= length;
+
+ return mem_buf_p->buffer;
+}
+
+static int mem_putc(
+ int c,
+ OUTDEST od
+)
+{
+ char string[ 1];
+
+ string[ 0] = (char) c;
+
+ if (append_to_buffer( &(mem_buffers[ od]), string, 1) != 0)
+ return 0;
+ else
+ return !0;
+}
+
+static int mem_puts(
+ const char * s,
+ OUTDEST od
+)
+{
+ if (append_to_buffer( &(mem_buffers[od]), s, ACE_OS::strlen(s)) != 0)
+ return 0;
+ else
+ return !0;
+}
+
+char * mcpp_get_mem_buffer(
+ OUTDEST od
+)
+{
+ return mem_buffers[ od].buffer;
+}
+
+#endif /* MCPP_LIB */
+
+#define DEST2FP(od) \
+ (od == OUT) ? fp_out : \
+ ((od == ERR) ? fp_err : \
+ ((od == DBG) ? fp_debug : \
+ (0)))
+
+/*
+ * The following mcpp_*() wrapper functions are intended to centralize
+ * the output generated by MCPP. They support memory buffer alternates to
+ * each of the primary output streams: out, err, debug. The memory buffer
+ * output option would be used in a setup where MCPP has been built as a
+ * function call - i.e. mcpp_lib_main().
+ */
+
+int mcpp_lib_fputc(
+ int c,
+ OUTDEST od
+)
+{
+#if MCPP_LIB
+ if (use_mem_buffers) {
+ return mem_putc( c, od);
+ } else {
+#endif
+ FILE * stream = DEST2FP( od);
+
+ return (stream != 0) ? ACE_OS::fputc( c, stream) : EOF;
+#if MCPP_LIB
+ }
+#endif
+}
+
+int (* mcpp_fputc)( int c, OUTDEST od) = mcpp_lib_fputc;
+
+int mcpp_lib_fputs(
+ const char * s,
+ OUTDEST od
+)
+{
+#if MCPP_LIB
+ if (use_mem_buffers) {
+ return mem_puts( s, od);
+ } else {
+#endif
+ FILE * stream = DEST2FP( od);
+
+ return (stream != 0) ? ACE_OS::fputs( s, stream) : EOF;
+#if MCPP_LIB
+ }
+#endif
+}
+
+int (* mcpp_fputs)( const char * s, OUTDEST od) = mcpp_lib_fputs;
+
+#include <ace/os_include/os_stdarg.h>
+
+int mcpp_lib_fprintf(
+ OUTDEST od,
+ const char * format,
+ ...
+)
+{
+ va_list ap;
+ FILE * stream = DEST2FP( od);
+
+ if (stream != 0) {
+ int rc;
+
+ va_start( ap, format);
+#if MCPP_LIB
+ if (use_mem_buffers) {
+ static char mem_buffer[ NWORK];
+
+ rc = ACE_OS::vsprintf( mem_buffer, format, ap);
+
+ if (rc != 0) {
+ rc = mem_puts( mem_buffer, od);
+ }
+ } else {
+#endif
+ rc = vfprintf( stream, format, ap);
+#if MCPP_LIB
+ }
+#endif
+ va_end( ap);
+
+ return rc;
+
+ } else {
+ return EOF;
+ }
+}
+
+int (* mcpp_fprintf)( OUTDEST od, const char * format, ...) = mcpp_lib_fprintf;
+
+#if MCPP_LIB
+void mcpp_reset_def_out_func( void)
+{
+ mcpp_fputc = mcpp_lib_fputc;
+ mcpp_fputs = mcpp_lib_fputs;
+ mcpp_fprintf = mcpp_lib_fprintf;
+}
+
+void mcpp_set_out_func(
+ int (* func_fputc)( int c, OUTDEST od),
+ int (* func_fputs)( const char * s, OUTDEST od),
+ int (* func_fprintf)( OUTDEST od, const char * format, ...)
+)
+{
+ mcpp_fputc = func_fputc;
+ mcpp_fputs = func_fputs;
+ mcpp_fprintf = func_fprintf;
+}
+#endif
+
+int get_unexpandable(
+ int c, /* First of token */
+ int diag /* Flag of diagnosis */
+)
+/*
+ * Get the next unexpandable token in the line, expanding macros.
+ * Return the token type. The token is written in work_buf[].
+ * The once expanded macro is never expanded again.
+ * Called only from the routines processing #if (#elif, #assert), #line and
+ * #include directives in order to diagnose some subtle macro expansions.
+ */
+{
+ DEFBUF * defp = 0;
+ FILEINFO * file;
+ FILE * fp = 0;
+ int token_type = NO_TOKEN;
+
+ while (c != EOS && c != '\n' /* In a line */
+ && (fp = infile->fp /* Preserve current state */
+ , (token_type
+ = scan_token( c, (workp = work_buf, &workp), work_end))
+ == NAM) /* Identifier */
+ && fp != 0 /* In source ! */
+ && (defp = is_macro( 0)) != 0) { /* Macro */
+ expand_macro( defp, work_buf, work_end); /* Expand macro call*/
+ file = unget_string( work_buf, defp->name); /* Stack to re-read */
+ c = skip_ws(); /* Skip TOK_SEP */
+ if (file != infile && macro_line != MACRO_ERROR && (warn_level & 1)) {
+ /* This diagnostic is issued even if "diag" is FALSE. */
+ cwarn( "Macro \"%s\" is expanded to 0 token" /* _W1_ */
+ , defp->name, 0L, 0);
+ if (! no_source_line)
+ dump_a_def( " macro", defp, FALSE, FALSE, TRUE, fp_err);
+ }
+ }
+
+ if (c == '\n' || c == EOS) {
+ unget_ch();
+ return NO_TOKEN;
+ }
+
+ if (diag && fp == 0 && defp && (warn_level & 1)) {
+ char tmp[ NWORK + 16];
+ char * tmp_end = tmp + NWORK;
+ char * tmp_p;
+ file = unget_string( infile->buffer, defp->name); /* To diagnose */
+ c = get_ch();
+ while (file == infile) { /* Search the expanded macro */
+ if (scan_token( c, (tmp_p = tmp, &tmp_p), tmp_end) != NAM) {
+ c = get_ch();
+ continue;
+ }
+ if (standard && str_eq( identifier, "defined")) {
+ cwarn( "Macro \"%s\" is expanded to \"defined\"" /* _W1_ */
+ , defp->name, 0L, 0);
+ break;
+ }
+ if (! standard && str_eq( identifier, "sizeof")) {
+ cwarn( "Macro \"%s\" is expanded to \"sizeof\"" /* _W1_ */
+ , defp->name, 0L, 0);
+ break;
+ }
+ c = get_ch();
+ }
+ if (file == infile) {
+ infile->bptr += ACE_OS::strlen( infile->bptr);
+ get_ch();
+ }
+ unget_ch();
+ if (token_type == OPE) {
+ unget_string( work_buf, 0); /* Set again 'openum' */
+ scan_token( get_ch(), (workp = work_buf, &workp), work_end);
+ }
+ }
+
+ return token_type;
+}
+
+void skip_nl( void)
+/*
+ * Skip to the end of the current input line.
+ */
+{
+ insert_sep = NO_SEP;
+ while (infile && infile->fp == 0) { /* Stacked text */
+ infile->bptr += ACE_OS::strlen( infile->bptr);
+ get_ch(); /* To the parent */
+ }
+ if (infile)
+ infile->bptr += ACE_OS::strlen( infile->bptr); /* Source line */
+}
+
+int skip_ws( void)
+/*
+ * Skip over whitespaces other than <newline>.
+ * Note: POST_STD mode does not use TOK_SEP, and KR mode does not use COM_SEP.
+ */
+{
+ int c;
+
+ do {
+ c = get_ch();
+ }
+ while (c == ' ' || c == TOK_SEP);
+ /* COM_SEP is an alias of TOK_SEP */
+ return c;
+}
+
+int scan_token(
+ int c, /* The first character of the token */
+ char ** out_pp, /* Pointer to pointer to output buf */
+ char * out_end /* End of output buffer */
+)
+/*
+ * Scan the next token of any type.
+ * The token is written out to the specified buffer and the output pointer
+ * is advanced. Token is terminated by EOS. Return the type of token.
+ * If the token is an identifier, the token is also in identifier[].
+ * If the token is a operator or punctuator, return OPE.
+ * If 'c' is token separator, then return SEP.
+ * If 'c' is not the first character of any known token and not a token
+ * separator, return SPE.
+ * In POST_STD mode, inserts token separator (a space) between any tokens of
+ * source.
+ */
+{
+ char * out = *out_pp; /* Output pointer */
+ int ch_type; /* Type of character */
+ int token_type = 0; /* Type of token */
+ int ch;
+
+ if (standard)
+ in_token = TRUE; /* While a token is scanned */
+ ch_type = char_type[ c & UCHARMAX] & mbmask;
+ c = c & UCHARMAX;
+
+ switch (ch_type) {
+ case LET: /* An identifier */
+ switch (c) {
+ case 'L':
+ if (! standard)
+ goto ident;
+ ch = get_ch();
+ if (char_type[ ch] & QUO) { /* char_type[ ch] == QUO */
+ if (ch == '"')
+ token_type = WSTR; /* Wide-char string literal */
+ else
+ token_type = WCHR; /* Wide-char constant */
+ c = ch;
+ *out++ = 'L';
+ break; /* Fall down to "case QUO:" */
+ } else {
+ unget_ch();
+ } /* Fall through */
+ default:
+ident:
+ scan_id( c);
+ out = stpcpy( out, identifier);
+ token_type = NAM;
+ break;
+ }
+ if (token_type == NAM)
+ break;
+ /* Else fall through -- i.e. WSTR, WCHR */
+ case QUO: /* String or character constant */
+ out = scan_quote( c, out, out_end, FALSE);
+ if (token_type == 0) {
+ if (c == '"')
+ token_type = STR;
+ else
+ token_type = CHR;
+ } /* Else WSTR or WCHR */
+ break;
+ case DOT:
+ ch = get_ch();
+ unget_ch();
+ if ((char_type[ ch] & DIG) == 0) /* Operator '.' or '...' */
+ goto operat;
+ /* Else fall through */
+ case DIG: /* Preprocessing number */
+ out = (standard ? scan_number( c, out, out_end)
+ : scan_number_prestd( c, out, out_end));
+ token_type = NUM;
+ break;
+ case PUNC:
+operat: out = scan_op( c, out); /* Operator or punctuator */
+ token_type = OPE; /* Number is set in global "openum" */
+ break;
+ default:
+#if OK_UCN
+ if (mcpp_mode == STD && c == '\\' && stdc2) {
+ ch = get_ch();
+ unget_ch();
+ if (ch == 'U' || ch == 'u')
+ goto ident; /* Universal-Characte-Name */
+ }
+#endif
+#if OK_MBIDENT
+ if (mcpp_mode == STD && (char_type[ c] & mbstart) && stdc3) {
+ char * bptr = infile->bptr;
+ mb_read( c, &infile->bptr, &out);
+ infile->bptr = bptr;
+ out = *out_pp;
+ goto ident;
+ }
+#endif
+ if ((standard && (c == CAT || c == ST_QUOTE)) || (char_type[ c] & SPA))
+ token_type = SEP; /* Token separator or magic char*/
+ else
+ token_type = SPE;
+ /* Unkown token ($, @, multi-byte character or Latin */
+ *out++ = c;
+ *out = EOS;
+ break;
+ }
+
+ if (out_end < out)
+ cfatal( "Buffer overflow scanning token \"%s\"" /* _F_ */
+ , *out_pp, 0L, 0);
+ if (mcpp_debug & TOKEN)
+ dump_token( token_type, *out_pp);
+ if (mcpp_mode == POST_STD && token_type != SEP && infile->fp != 0
+ && (char_type[ *infile->bptr & UCHARMAX] & SPA) == 0)
+ insert_sep = INSERT_SEP; /* Insert token separator */
+ *out_pp = out;
+
+ in_token = FALSE; /* Token scanning has been done */
+ return token_type;
+}
+
+static void scan_id(
+ int c /* First char of id */
+)
+/*
+ * Reads the next identifier and put it into identifier[].
+ * The caller has already read the first character of the identifier.
+ */
+{
+#if DOLLAR_IN_NAME
+ static int diagnosed = FALSE; /* Flag of diagnosing '$' */
+#endif
+ static char * const limit = &identifier[ IDMAX];
+#if OK_UCN
+ int uc2 = 0, uc4 = 0; /* Count of UCN16, UCN32 */
+#endif
+#if OK_MBIDENT
+ int mb = 0; /* Count of MBCHAR */
+#endif
+ size_t len; /* Length of identifier */
+ char * bp = identifier;
+
+ do {
+ if (bp < limit)
+ *bp++ = c;
+#if OK_UCN
+ if (mcpp_mode == STD && c == '\\' && stdc2) {
+ int cnt;
+ char * tp = bp;
+
+ if ((c = get_ch()) == 'u') {
+ cnt = 4;
+ } else if (c == 'U') {
+ cnt = 8;
+ } else {
+ unget_ch();
+ bp--;
+ break;
+ }
+ *bp++ = c;
+ if ((bp = scan_ucn( cnt, bp)) == 0) /* Error */
+ return;
+ if (cnt == 4)
+ uc2++;
+ else if (cnt == 8)
+ uc4++;
+ if (limit <= tp) /* Too long identifier */
+ bp = tp; /* Back the pointer */
+ goto next_c;
+ }
+#endif /* OK_UCN */
+#if OK_MBIDENT
+ if (mcpp_mode == STD && (char_type[ c] & mbstart) && stdc3) {
+ len = mb_read( c, &infile->bptr, &bp);
+ if (len & MB_ERROR) {
+ if (infile->fp)
+ cerror(
+ "Illegal multi-byte character sequence." /* _E_ */
+ , 0, 0L, 0);
+ } else {
+ mb += len;
+ }
+ }
+#endif /* OK_MBIDENT */
+#if OK_UCN
+next_c:
+#endif
+ c = get_ch();
+ } while ((char_type[ c] & (LET | DIG)) /* Letter or digit */
+#if OK_UCN
+ || (mcpp_mode == STD && c == '\\' && stdc2)
+#endif
+#if OK_MBIDENT
+ || (mcpp_mode == STD && (char_type[ c] & mbstart) && stdc3)
+#endif
+ );
+
+ unget_ch();
+ *bp = EOS;
+
+ if (bp >= limit && (warn_level & 1)) /* Limit of token */
+ cwarn( "Too long identifier truncated to \"%s\"" /* _W1_ */
+ , identifier, 0L, 0);
+
+ len = bp - identifier;
+#if IDMAX > IDLEN90MIN
+ /* UCN16, UCN32, MBCHAR are counted as one character for each. */
+#if OK_UCN
+ if (mcpp_mode == STD)
+ len -= (uc2 * 5) - (uc4 * 9);
+#endif
+#if OK_MBIDENT
+ if (mcpp_mode == STD)
+ len -= mb;
+#endif
+ if (standard && infile->fp && len > id_len_min && (warn_level & 4))
+ cwarn( "Identifier longer than %.0s%ld characters \"%s\"" /* _W4_ */
+ , 0, (long) id_len_min, identifier);
+#endif /* IDMAX > IDLEN90MIN */
+
+#if DOLLAR_IN_NAME
+ if (diagnosed == FALSE && (warn_level & 2)
+ && ACE_OS::strchr( identifier, '$') != 0) {
+ cwarn( "'$' in identifier \"%s\"", identifier, 0L, 0); /* _W2_ */
+ diagnosed = TRUE; /* Diagnose only once */
+ }
+#endif
+}
+
+char * scan_quote(
+ int delim, /* ', " or < (header-name) */
+ char * out, /* Output buffer */
+ char * out_end, /* End of output buffer */
+ int diag /* Diagnostic should be output */
+)
+/*
+ * Scan off a string literal or character constant to the output buffer.
+ * Report diagnosis if the quotation is terminated by newline or character
+ * constant is empty (provided 'diag' is TRUE).
+ * Return the next output pointer or 0 (on error).
+ */
+{
+ const char * const skip_line = ", skipped the line"; /* _E_ */
+ const char * const unterm_string
+ = "Unterminated string literal%s";
+ const char * const unterm_char
+ = "Unterminated character constant %s%.0ld%s";
+ const char * skip;
+ size_t len;
+ int c;
+ char * out_p = out;
+
+ /* Set again in case of called from routines other than scan_token(). */
+ if (standard)
+ in_token = TRUE;
+ *out_p++ = delim;
+ if (delim == '<')
+ delim = '>';
+
+scan:
+ while ((c = get_ch()) != EOS) {
+
+#if MBCHAR
+ if (char_type[ c] & mbstart) {
+ /* First of multi-byte character (or shift-sequence) */
+ char * bptr = infile->bptr;
+ len = mb_read( c, &infile->bptr, (*out_p++ = c, &out_p));
+ if (len & MB_ERROR) {
+ if (infile->fp != 0 && compiling && diag) {
+ if (warn_level & 1) {
+ char * buf;
+ size_t chlen;
+ buf = xmalloc( chlen = infile->bptr - bptr + 2);
+ ACE_OS::memcpy( buf, bptr, chlen - 1);
+ buf[ chlen - 1] = EOS;
+ cwarn(
+ "Illegal multi-byte character sequence \"%s\" in quotation", /* _W1_ */
+ buf, 0L, 0);
+ ACE_OS::free( buf);
+ }
+ }
+ continue;
+ } else { /* Valid multi-byte character (or sequence) */
+ goto chk_limit;
+ }
+ }
+#endif
+ if (c == delim) {
+ break;
+ } else if (c == '\\' && delim != '>') { /* In string literal */
+#if OK_UCN
+ if (mcpp_mode == STD && stdc2) {
+ int cnt;
+ char * tp;
+
+ *out_p++ = c;
+ if ((c = get_ch()) == 'u') {
+ cnt = 4;
+ } else if (c == 'U') {
+ cnt = 8;
+ } else {
+ goto escape;
+ }
+ *out_p++ = c;
+ if ((tp = scan_ucn( cnt, out_p)) != 0)
+ out_p = tp;
+ /* Else error */
+ continue; /* Error or not, anyway continue */
+ }
+#endif /* OK_UCN */
+ *out_p++ = c; /* Escape sequence */
+ c = get_ch();
+escape:
+#if MBCHAR
+ if (char_type[ c] & mbstart) {
+ /* '\\' followed by multi-byte char */
+ unget_ch();
+ continue;
+ }
+#endif
+ if (! standard && c == '\n') { /* <backslash><newline> */
+ out_p--; /* Splice the lines */
+ if (cat_line( TRUE) == 0) /* End of file */
+ break;
+ c = get_ch();
+ }
+ } else if (mcpp_mode == POST_STD && c == ' ' && delim == '>'
+ && infile->fp == 0) {
+ continue; /* Skip space possibly inserted by macro expansion */
+ } else if (c == '\n') {
+ break;
+ }
+ if (diag && ACE_OS::ace_iscntrl( c) && ((char_type[ c] & SPA) == 0)
+ && (warn_level & 1))
+ cwarn(
+ "Illegal control character %.0s0lx%02x in quotation" /* _W1_ */
+ , 0, (long) c, 0);
+ *out_p++ = c;
+chk_limit:
+ if (out_end < out_p) {
+ *out_end = EOS;
+ cfatal( "Too long quotation", 0, 0L, 0); /* _F_ */
+ }
+ }
+
+ if (c == '\n' || c == EOS)
+ unget_ch();
+ if (c == delim)
+ *out_p++ = delim;
+ *out_p = EOS;
+ if (diag) { /* At translation phase 3 */
+ skip = (infile->fp == 0) ? 0 : skip_line;
+ if (c != delim) {
+ if (mcpp_mode == OLD_PREP /* Implicit closing of quote*/
+ && (delim == '"' || delim == '\''))
+ goto done;
+ if (delim == '"') {
+ if (mcpp_mode != POST_STD && lang_asm) { /* STD, KR */
+ /* Concatenate the unterminated string to the next line */
+ if (warn_level & 1)
+ cwarn( unterm_string
+ , ", catenated to the next line" /* _W1_ */
+ , 0L, 0);
+ if (cat_line( FALSE) != 0)
+ goto scan; /* Splice the lines */
+ /* Else end of file */
+ } else {
+ cerror( unterm_string, skip, 0L, 0); /* _E_ */
+ }
+ } else if (delim == '\'') {
+ if (mcpp_mode != POST_STD && lang_asm) { /* STD, KR */
+ if (warn_level & 1)
+ cwarn( unterm_char, out, 0L, 0); /* _W1_ */
+ goto done;
+ } else {
+ cerror( unterm_char, out, 0L, skip); /* _E_ */
+ }
+ } else {
+ cerror( "Unterminated header name %s%.0ld%s" /* _E_ */
+ , out, 0L, skip);
+ }
+ out_p = 0;
+ } else if (delim == '\'' && out_p - out <= 2) {
+ cerror( "Empty character constant %s%.0ld%s" /* _E_ */
+ , out, 0L, skip);
+ out_p = 0;
+ }
+ else if (mcpp_mode == POST_STD && delim == '>' && (warn_level & 2))
+ cwarn(
+ "Header-name enclosed by <, > is an obsolescent feature %s" /* _W2_ */
+ , out, 0L, skip);
+#if NWORK-2 > SLEN90MIN
+ if (standard && out_p - out > str_len_min && (warn_level & 4))
+ cwarn( "Quotation longer than %.0s%ld bytes" /* _W4_ */
+ , 0, str_len_min, 0);
+#endif
+ }
+
+done:
+ in_token = FALSE;
+ return out_p;
+}
+
+static char * cat_line(
+ int del_bsl /* Delete the <backslash><newline> ? */
+)
+/*
+ * If del_bsl == TRUE:
+ * Delete <backslash><newline> sequence in string literal.
+ * FALSE: Overwrite the <newline> with <backslash>'n'.
+ * Return 0 on end of file. Called only from scan_quote().
+ * This routine is never called in POST_STD mode.
+ */
+{
+ size_t len;
+ char * save1, * save2;
+
+ if (del_bsl) { /* Delete the <backslash><newline> */
+ infile->bptr -= 2;
+ len = infile->bptr - infile->buffer;
+ } else { /* Overwrite the <newline> with <backslash>'n' */
+ ACE_OS::strcpy( infile->bptr, "\\n");
+ len = ACE_OS::strlen( infile->buffer);
+ }
+ save1 = save_string( infile->buffer);
+ save2 = get_line( FALSE); /* infile->buffer is overwritten */
+ if (save2 == 0) {
+ ACE_OS::free( save1);
+ return 0;
+ }
+ save2 = save_string( infile->buffer);
+ ACE_OS::memcpy( infile->buffer, save1, len);
+ ACE_OS::strcpy( infile->buffer + len, save2); /* Catenate */
+ ACE_OS::free( save1);
+ ACE_OS::free( save2);
+ if (! del_bsl)
+ len -= 2;
+ infile->bptr = infile->buffer + len;
+ return infile->bptr;
+}
+
+static char * scan_number(
+ int c, /* First char of number */
+ char * out, /* Output buffer */
+ char * out_end /* Limit of output buffer */
+)
+/*
+ * Read a preprocessing number. We know that c is from 0 to 9 or dot, and if
+ * c is dot then the next character is digit.
+ * Returns the advanced output pointer.
+ * Note: preprocessing number permits non-numeric forms such as 3E+xy,
+ * which are used in stringization or token-concatenation.
+ */
+{
+ char * out_p = out; /* Current output pointer */
+
+ do {
+ *out_p++ = c;
+ if (c == 'E' || c == 'e' /* Sign should follow 'E', 'e', */
+ || (stdc3 && (c == 'P' || c == 'p'))
+ /* 'P' or 'p'. */
+ ) {
+ c = get_ch();
+ if (c == '+' || c == '-') {
+ *out_p++ = c;
+ c = get_ch();
+ }
+#if OK_UCN
+ } else if (mcpp_mode == STD && c == '\\' && stdc3) {
+ int cnt;
+ char * tp;
+
+ if ((c = get_ch()) == 'u') {
+ cnt = 4;
+ } else if (c == 'U') {
+ cnt = 8;
+ } else {
+ unget_ch();
+ out_p--;
+ break;
+ }
+ *out_p++ = c;
+ if ((tp = scan_ucn( cnt, out_p)) == 0) /* Error */
+ break;
+ else
+ out_p = tp;
+ c = get_ch();
+#endif /* OK_UCN */
+#if OK_MBIDENT
+ } else if (mcpp_mode == STD && (char_type[ c] & mbstart) && stdc3) {
+ len = mb_read( c, &infile->bptr, &out_p);
+ if (len & MB_ERROR) {
+ if (infile->fp)
+ cerror(
+ "Illegal multi-byte character sequence." /* _E_ */
+ , 0, 0L, 0);
+ }
+#endif /* OK_MBIDENT */
+ } else {
+ c = get_ch();
+ }
+ } while ((char_type[ c] & (DIG | DOT | LET)) /* Digit, dot or letter */
+#if OK_UCN
+ || (mcpp_mode == STD && c == '\\' && stdc3)
+#endif
+#if OK_MBIDENT
+ || (mcpp_mode == STD && (char_type[ c] & mbstart) && stdc3)
+#endif
+ );
+
+ *out_p = EOS;
+ if (out_end < out_p)
+ cfatal( "Too long pp-number token \"%s\"" /* _F_ */
+ , out, 0L, 0);
+ unget_ch();
+ return out_p;
+}
+
+/* Original version of DECUS CPP, too exact for Standard preprocessing. */
+static char * scan_number_prestd(
+ int c, /* First char of number */
+ char * out, /* Output buffer */
+ char * out_end /* Limit of output buffer */
+)
+/*
+ * Process a number. We know that c is from 0 to 9 or dot.
+ * Algorithm from Dave Conroy's Decus C.
+ * Returns the advanced output pointer.
+ */
+{
+ char * const out_s = out; /* For diagnostics */
+ int radix; /* 8, 10, or 16 */
+ int expseen; /* 'e' seen in floater */
+ int octal89; /* For bad octal test */
+ int dotflag; /* TRUE if '.' was seen */
+
+ expseen = FALSE; /* No exponent seen yet */
+ octal89 = FALSE; /* No bad octal yet */
+ radix = 10; /* Assume decimal */
+ if ((dotflag = (c == '.')) != FALSE) { /* . something? */
+ *out++ = '.'; /* Always out the dot */
+ if ((char_type[(c = get_ch())] & DIG) == 0) {
+ /* If not a float numb, */
+ goto nomore; /* All done for now */
+ }
+ } /* End of float test */
+ else if (c == '0') { /* Octal or hex? */
+ *out++ = c; /* Stuff initial zero */
+ radix = 8; /* Assume it's octal */
+ c = get_ch(); /* Look for an 'x' */
+ if (c == 'x' || c == 'X') { /* Did we get one? */
+ radix = 16; /* Remember new radix */
+ *out++ = c; /* Stuff the 'x' */
+ c = get_ch(); /* Get next character */
+ }
+ }
+ while (1) { /* Process curr. char. */
+ /*
+ * Note that this algorithm accepts "012e4" and "03.4"
+ * as legitimate floating-point numbers.
+ */
+ if (radix != 16 && (c == 'e' || c == 'E')) {
+ if (expseen) /* Already saw 'E'? */
+ break; /* Exit loop, bad nbr. */
+ expseen = TRUE; /* Set exponent seen */
+ radix = 10; /* Decimal exponent */
+ *out++ = c; /* Output the 'e' */
+ if ((c = get_ch()) != '+' && c != '-')
+ continue;
+ }
+ else if (radix != 16 && c == '.') {
+ if (dotflag) /* Saw dot already? */
+ break; /* Exit loop, two dots */
+ dotflag = TRUE; /* Remember the dot */
+ radix = 10; /* Decimal fraction */
+ }
+ else { /* Check the digit */
+ switch (c) {
+ case '8': case '9': /* Sometimes wrong */
+ octal89 = TRUE; /* Do check later */
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ break; /* Always ok */
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ if (radix == 16) /* Alpha's are ok only */
+ break; /* if reading hex. */
+ default: /* At number end */
+ goto done; /* Break from for loop */
+ } /* End of switch */
+ } /* End general case */
+ *out++ = c; /* Accept the character */
+ c = get_ch(); /* Read another char */
+ } /* End of scan loop */
+
+ if (out_end < out) /* Buffer overflow */
+ goto nomore;
+ /*
+ * When we break out of the scan loop, c contains the first
+ * character (maybe) not in the number. If the number is an
+ * integer, allow a trailing 'L' for long. for unsigned. If not
+ * those, push the trailing character back on the input stream.
+ * Floating point numbers accept a trailing 'L' for "long double"
+ * or a trailing 'F' for explicit float.
+ */
+done:
+ if (! (dotflag || expseen)) { /* Not floating point */
+ /*
+ * We know that dotflag and expseen are both zero, now:
+ * dotflag signals "saw 'L'".
+ * We assume that 12F is not a floating constant.
+ */
+ for (;;) {
+ switch (c) {
+ case 'l':
+ case 'L':
+ if (dotflag)
+ goto nomore;
+ dotflag = TRUE;
+ break;
+ default:
+ goto nomore;
+ }
+ *out++ = c; /* Got 'L' . */
+ c = get_ch(); /* Look at next, too. */
+ }
+ }
+
+nomore: *out = EOS;
+ if (out_end < out)
+ goto overflow;
+ unget_ch(); /* Not part of a number */
+ if (octal89 && radix == 8 && (warn_level & 1))
+ cwarn( "Illegal digit in octal number \"%s\"" /* _W1_ */
+ , out_s, 0L, 0);
+ return out;
+
+overflow:
+ cfatal( "Too long number token \"%s\"", out_s, 0L, 0); /* _F_ */
+ return out;
+}
+
+#if OK_UCN
+static char * scan_ucn(
+ int cnt, /* Bytes of sequence */
+ char * out /* Output buffer */
+)
+/*
+ * Scan an UCN sequence and put the sequence to 'out'.
+ * Return the advanced pointer or 0 on failure.
+ * This routine is never called in POST_STD mode.
+ */
+{
+ uexpr_t value; /* Value of UCN */
+ int i, c;
+
+ value = 0L;
+ for (i = 0; i < cnt; i++) {
+ c = get_ch();
+ if (! ACE_OS::ace_isxdigit( c)) {
+ if (infile->fp)
+ cerror( "Illegal UCN sequence" /* _E_ */
+ , 0, 0L, 0);
+ *out = EOS;
+ unget_ch();
+ return 0;
+ }
+ c = ACE_OS::ace_tolower( c);
+ *out++ = c;
+ c = (ACE_OS::ace_isdigit( c) ? (c - '0') : (c - 'a' + 10));
+ value = (value << 4) | c;
+ }
+ if (infile->fp /* In source */
+ && ((/*value >= 0L &&*/ value <= 0x9FL
+ && value != 0x24L && value != 0x40L && value != 0x60L)
+ /* Basic source character */
+ || (stdc3 && (value >= 0xD800L && value <= 0xDFFFL))))
+ /* Reserved for special chars */
+ cerror( "UCN cannot specify the value %.0s\"%08lx\"" /* _E_ */
+ , 0, (long) value, 0);
+ return out;
+}
+#endif /* OK_UCN */
+
+static char * scan_op(
+ int c, /* First char of the token */
+ char * out /* Output buffer */
+)
+/*
+ * Scan C operator or punctuator into the specified buffer.
+ * Return the advanced output pointer.
+ * The code-number of the operator is stored to global variable 'openum'.
+ * Note: '#' is not an operator nor a punctuator in other than control line,
+ * nevertheless is handled as a punctuator in this cpp for convenience.
+ */
+{
+ int c2, c3, c4;
+
+ *out++ = c;
+
+ switch (c) {
+ case '~': openum = OP_COM; break;
+ case '(': openum = OP_LPA; break;
+ case ')': openum = OP_RPA; break;
+ case '?': openum = OP_QUE; break;
+ case ';': case '[': case ']': case '{':
+ case '}': case ',':
+ openum = OP_1;
+ break;
+ default:
+ openum = OP_2; /* Tentative guess */
+ }
+
+ if (openum != OP_2) { /* Single byte operators */
+ *out = EOS;
+ return out;
+ }
+
+ c2 = get_ch(); /* Possibly two bytes ops */
+ *out++ = c2;
+
+ switch (c) {
+ case '=':
+ openum = ((c2 == '=') ? OP_EQ : OP_1); /* ==, = */
+ break;
+ case '!':
+ openum = ((c2 == '=') ? OP_NE : OP_NOT); /* !=, ! */
+ break;
+ case '&':
+ switch (c2) {
+ case '&': openum = OP_ANA; break; /* && */
+ case '=': /* openum = OP_2; */ break; /* &= */
+ default : openum = OP_AND; break; /* & */
+ }
+ break;
+ case '|':
+ switch (c2) {
+ case '|': openum = OP_ORO; break; /* || */
+ case '=': /* openum = OP_2; */ break; /* |= */
+ default : openum = OP_OR; break; /* | */
+ }
+ break;
+ case '<':
+ switch (c2) {
+ case '<': c3 = get_ch();
+ if (c3 == '=') {
+ openum = OP_3; /* <<= */
+ *out++ = c3;
+ } else {
+ openum = OP_SL; /* << */
+ unget_ch();
+ }
+ break;
+ case '=': openum = OP_LE; break; /* <= */
+ case ':': /* <: i.e. [ */
+ if (mcpp_mode == STD && dig_flag)
+ openum = OP_LBRCK_D;
+ else
+ openum = OP_LT;
+ break;
+ case '%': /* <% i.e. { */
+ if (mcpp_mode == STD && dig_flag)
+ openum = OP_LBRACE_D;
+ else
+ openum = OP_LT;
+ break;
+ default : openum = OP_LT; break; /* < */
+ }
+ break;
+ case '>':
+ switch (c2) {
+ case '>': c3 = get_ch();
+ if (c3 == '=') {
+ openum = OP_3; /* >>= */
+ *out++ = c3;
+ } else {
+ openum = OP_SR; /* >> */
+ unget_ch();
+ }
+ break;
+ case '=': openum = OP_GE; break; /* >= */
+ default : openum = OP_GT; break; /* > */
+ }
+ break;
+ case '#':
+ if (standard && (in_define || macro_line)) /* in #define or macro */
+ openum = ((c2 == '#') ? OP_CAT : OP_STR); /* ##, # */
+ else
+ openum = OP_1; /* # */
+ break;
+ case '+':
+ switch (c2) {
+ case '+': /* ++ */
+ case '=': /* openum = OP_2; */ break; /* += */
+ default : openum = OP_ADD; break; /* + */
+ }
+ break;
+ case '-':
+ switch (c2) {
+ case '-': /* -- */
+ case '=': /* -= */
+ /* openum = OP_2; */
+ break;
+ case '>':
+ if (cplus_val) {
+ if ((c3 = get_ch()) == '*') { /* ->* */
+ openum = OP_3;
+ *out++ = c3;
+ } else {
+ /* openum = OP_2; */
+ unget_ch();
+ }
+ } /* else openum = OP_2; */ /* -> */
+ /* else openum = OP_2; */
+ break;
+ default : openum = OP_SUB; break; /* - */
+ }
+ break;
+ case '%':
+ switch (c2) {
+ case '=': break; /* %= */
+ case '>': /* %> i.e. } */
+ if (mcpp_mode == STD && dig_flag)
+ openum = OP_RBRACE_D;
+ else
+ openum = OP_MOD;
+ break;
+ case ':':
+ if (mcpp_mode == STD && dig_flag) {
+ if ((c3 = get_ch()) == '%') {
+ if ((c4 = get_ch()) == ':') { /* %:%: i.e. ## */
+ openum = OP_DSHARP_D;
+ *out++ = c3;
+ *out++ = c4;
+ } else {
+ unget_ch();
+ unget_ch();
+ openum = OP_SHARP_D; /* %: i.e. # */
+ }
+ } else {
+ unget_ch();
+ openum = OP_SHARP_D; /* %: i.e. # */
+ }
+ if (in_define) { /* in #define */
+ if (openum == OP_DSHARP_D)
+ openum = OP_CAT;
+ else
+ openum = OP_STR;
+ }
+ } else {
+ openum = OP_MOD;
+ }
+ break;
+ default : openum = OP_MOD; break; /* % */
+ }
+ break;
+ case '*':
+ if (c2 != '=') /* * */
+ openum = OP_MUL;
+ /* else openum = OP_2; */ /* *= */
+ break;
+ case '/':
+ if (c2 != '=') /* / */
+ openum = OP_DIV;
+ /* else openum = OP_2; */ /* /= */
+ break;
+ case '^':
+ if (c2 != '=') /* ^ */
+ openum = OP_XOR;
+ /* else openum = OP_2; */ /* ^= */
+ break;
+ case '.':
+ if (standard) {
+ if (c2 == '.') {
+ c3 = get_ch();
+ if (c3 == '.') {
+ openum = OP_ELL; /* ... */
+ *out++ = c3;
+ break;
+ } else {
+ unget_ch();
+ openum = OP_1;
+ }
+ } else if (cplus_val && c2 == '*') { /* .* */
+ /* openum = OP_2 */ ;
+ } else { /* . */
+ openum = OP_1;
+ }
+ } else {
+ openum = OP_1;
+ }
+ break;
+ case ':':
+ if (cplus_val && c2 == ':') /* :: */
+ /* openum = OP_2 */ ;
+ else if (mcpp_mode == STD && c2 == '>' && dig_flag)
+ openum = OP_RBRCK_D; /* :> i.e. ] */
+ else /* : */
+ openum = OP_COL;
+ break;
+ default: /* Who knows ? */
+ cfatal( "Bug: Punctuator is mis-implemented %.0s0lx%x" /* _F_ */
+ , 0, (long) c, 0);
+ openum = OP_1;
+ break;
+ }
+
+ switch (openum) {
+ case OP_STR:
+ if (mcpp_mode == STD && c == '%') break; /* %: */
+ case OP_1:
+ case OP_NOT: case OP_AND: case OP_OR: case OP_LT:
+ case OP_GT: case OP_ADD: case OP_SUB: case OP_MOD:
+ case OP_MUL: case OP_DIV: case OP_XOR: case OP_COM:
+ case OP_COL: /* Any single byte operator or punctuator */
+ unget_ch();
+ out--;
+ break;
+ default: /* Two or more bytes operators or punctuators */
+ break;
+ }
+
+ *out = EOS;
+ return out;
+}
+
+int id_operator(
+ const char * name
+)
+/*
+ * Check whether the name is identifier-like operator in C++.
+ * Return the operator number if matched, return 0 if not matched.
+ * Note: these identifiers are defined as macros in <iso646.h> in C95.
+ * This routine is never called in POST_STD mode.
+ */
+{
+ typedef struct id_op {
+ const char * name;
+ int op_num;
+ } ID_OP;
+
+ ID_OP id_ops[] = {
+ { "and", OP_ANA},
+ { "and_eq", OP_2},
+ { "bitand", OP_AND},
+ { "bitor", OP_OR},
+ { "compl", OP_COM},
+ { "not", OP_NOT},
+ { "not_eq", OP_NE},
+ { "or", OP_ORO},
+ { "or_eq", OP_2},
+ { "xor", OP_XOR},
+ { "xor_eq", OP_2},
+ { 0, 0},
+ };
+
+ ID_OP * id_p = id_ops;
+
+ while (id_p->name != 0) {
+ if (str_eq( name, id_p->name))
+ return id_p->op_num;
+ id_p++;
+ }
+ return 0;
+}
+
+void expanding(
+ const char * name, /* The name of (nested) macro just expanded. */
+ int to_be_freed /* The name should be freed later. */
+)
+/*
+ * Remember used macro name for diagnostic.
+ */
+{
+ if (exp_mac_ind < EXP_MAC_IND_MAX - 1) {
+ exp_mac_ind++;
+ } else {
+ clear_exp_mac();
+ exp_mac_ind++;
+ }
+ expanding_macro[ exp_mac_ind].name = name;
+ expanding_macro[ exp_mac_ind].to_be_freed = to_be_freed;
+}
+
+void clear_exp_mac( void)
+/*
+ * Initialize expanding_macro[] freeing names registered in
+ * name_to_be_freed[].
+ */
+{
+ int i;
+
+ for (i = 1; i < EXP_MAC_IND_MAX; i++) {
+ if (expanding_macro[ i].to_be_freed) {
+ ACE_OS::free( (void *) expanding_macro[ i].name);
+ expanding_macro[ i].to_be_freed = FALSE;
+ }
+ }
+ exp_mac_ind = 0;
+}
+
+int get_ch( void)
+/*
+ * Return the next character from a macro or the current file.
+ * Always return the value representable by unsigned char.
+ */
+{
+ int len;
+ int c;
+ FILEINFO * file;
+
+ /*
+ * 'in_token' is set to TRUE while scan_token() is executed (and
+ * scan_id(), scan_quote(), scan_number(), scan_ucn() and scan_op()
+ * via scan_token()) in Standard mode to simplify tokenization.
+ * Any token cannot cross "file"s.
+ */
+ if (in_token)
+ return (*infile->bptr++ & UCHARMAX);
+
+ if ((file = infile) == 0)
+ return CHAR_EOF; /* End of all input */
+
+ if (mcpp_mode == POST_STD && file->fp) { /* In a source file */
+ switch (insert_sep) {
+ case NO_SEP:
+ break;
+ case INSERT_SEP: /* Insert a token separator */
+ insert_sep = INSERTED_SEP; /* Remember this fact */
+ return ' '; /* for unget_ch(). */
+ case INSERTED_SEP: /* Has just inserted */
+ insert_sep = NO_SEP; /* Clear the flag */
+ break;
+ }
+ }
+ if (! standard && squeezews) {
+ if (*file->bptr == ' ')
+ file->bptr++; /* Squeeze white spaces */
+ squeezews = FALSE;
+ }
+
+ if (mcpp_debug & GETC) {
+ mcpp_fprintf( DBG, "get_ch(%s), line %ld, bptr = %d, buffer"
+ , file->fp ? cur_fullname : file->real_fname ? file->real_fname
+ : file->filename ? file->filename : "0"
+ , src_line, (int) (file->bptr - file->buffer));
+ dump_string( 0, file->buffer);
+ dump_unget( "get entrance");
+ }
+
+ /*
+ * Read a character from the current input logical line or macro.
+ * At EOS, either finish the current macro (freeing temporary storage)
+ * or get another logical line by parse_line().
+ * At EOF, exit the current file (#included) or, at EOF from the MCPP input
+ * file, return CHAR_EOF to finish processing.
+ * The character is converted to int with no sign-extension.
+ */
+ if ((c = (*file->bptr++ & UCHARMAX)) != EOS) {
+ if (standard)
+ return c; /* Just a character */
+ if (! in_string && c == '\\' && *file->bptr == '\n'
+ && in_define /* '\\''\n' is deleted in #define line, */
+ /* provided the '\\' is not the 2nd byte of mbchar. */
+ && ! last_is_mbchar( file->buffer, ACE_OS::strlen( file->buffer) - 2)
+ ) {
+ if (*(file->bptr - 2) == ' ')
+ squeezews = TRUE;
+ } else {
+ return c;
+ }
+ }
+
+ /*
+ * Nothing in current line or macro. Get next line (if input from a
+ * file), or do end of file/macro processing, and reenter get_ch() to
+ * restart from the top.
+ */
+ if (file->fp && /* In source file */
+ parse_line() != 0) /* Get line from file */
+ return get_ch();
+ /*
+ * Free up space used by the (finished) file or macro and restart
+ * input from the parent file/macro, if any.
+ */
+ infile = file->parent; /* Unwind file chain */
+ ACE_OS::free( file->buffer); /* Free buffer */
+ if (infile == 0) { /* If at end of input, */
+ if (file->filename)
+ ACE_OS::free( file->filename); /* Free filename */
+ ACE_OS::free( file);
+ return CHAR_EOF; /* return end of file.*/
+ }
+ if (file->fp) { /* Source file included */
+ char * cp;
+
+ ACE_OS::free( file->filename); /* Free filename */
+ file->filename = 0;
+ ACE_OS::fclose( file->fp); /* Close finished file */
+ cp = stpcpy( cur_fullname, *(infile->dirp));
+ ACE_OS::strcpy( cp, infile->real_fname);
+ cur_fname = infile->real_fname; /* Restore current fname*/
+ if (infile->pos != 0L) { /* Includer was closed */
+ infile->fp = ACE_OS::fopen( cur_fullname, "r");
+ ACE_OS::fseek( infile->fp, infile->pos, SEEK_SET);
+ } /* Re-open the includer and restore the file-position */
+ len = (int) (infile->bptr - infile->buffer);
+ infile->buffer = xrealloc( infile->buffer, NBUFF);
+ /* Restore full size buffer to get the next line */
+ infile->bptr = infile->buffer + len;
+ src_line = infile->line; /* Reset line number */
+ inc_dirp = infile->dirp; /* Includer's directory */
+#if MCPP_LIB
+ mcpp_set_out_func( infile->last_fputc, infile->last_fputs,
+ infile->last_fprintf);
+#endif
+ include_nest--;
+ src_line++; /* Next line to #include*/
+ sharp(); /* Need a #line now */
+ src_line--;
+ newlines = 0; /* Clear the blank lines*/
+ } else if (file->filename) { /* Expanding macro */
+ if (macro_name) /* file->filename should be freed later */
+ expanding( file->filename, TRUE);
+ else
+ ACE_OS::free( file->filename);
+ }
+ ACE_OS::free( file); /* Free file space */
+ return get_ch(); /* Get from the parent */
+}
+
+static char * parse_line( void)
+/*
+ * ANSI (ISO) C: translation phase 3.
+ * Parse a logical line.
+ * Check illegal control characters.
+ * Check unterminated string literal, character constant or comment.
+ * Convert each comment to one space.
+ * Squeeze succeding white spaces other than <newline> (including comments) to
+ * one space.
+ * The lines might be spliced by comments which cross the lines.
+ */
+{
+ char * temp; /* Temporary buffer */
+ char * limit; /* Buffer end */
+ char * tp; /* Current pointer into temporary buffer */
+ char * sp; /* Pointer into input buffer */
+ int c;
+
+ if ((sp = get_line( FALSE)) == 0) /* Next logical line */
+ return 0; /* End of a file */
+ if (in_asm) { /* In #asm block */
+ while (char_type[ *sp++ & UCHARMAX] & SPA)
+ ;
+ if (*--sp == '#') /* Directive line */
+ infile->bptr = sp;
+ return infile->bptr; /* Don't tokenize */
+ }
+ tp = temp = xmalloc( (size_t) NBUFF);
+ limit = temp + NBUFF - 2;
+
+ if (mcpp_mode == POST_STD) {
+ while (((c = *sp++ & UCHARMAX) == ' ') || c == '\t')
+ ; /* Skip the line top spaces */
+ } else {
+ /* Putout the line top spaces as they are */
+ while (((c = *sp++ & UCHARMAX) == ' ') || c == '\t')
+ *tp++ = c;
+ }
+ sp--;
+
+ while ((c = *sp++ & UCHARMAX) != '\n') {
+
+ switch (c) {
+ case '/':
+ switch (*sp++) {
+ case '*': /* Start of a comment */
+ if ((sp = read_a_comment( sp)) == 0) {
+ ACE_OS::free( temp); /* End of file with un- */
+ return 0; /* terminated comment */
+ }
+ if (mcpp_mode == POST_STD && (temp < tp && *(tp - 1) != ' '))
+ *tp++ = ' '; /* Skip line top spaces */
+ else if (mcpp_mode == OLD_PREP && (temp == tp
+ || (*(tp - 1) != ' ' && *(tp - 1) != COM_SEP)))
+ *tp++ = COM_SEP; /* Convert to magic character */
+ else if (temp == tp || *(tp - 1) != ' ')
+ *tp++ = ' '; /* Squeeze white spaces */
+ break;
+ case '/': /* // */
+ if (! standard)
+ goto not_comment;
+ /* Comment when C++ or __STDC_VERSION__ >= 199901L */
+ /* Need not to convert to a space because '\n' follows */
+ if (! stdc2 && (warn_level & 2))
+ cwarn( "Parsed \"//\" as comment" /* _W2_ */
+ , 0, 0L, 0);
+ if (keep_comments) {
+ sp -= 2;
+ while (*sp != '\n')
+ mcpp_fputc( *sp++, OUT); /* Until end of line */
+ wrong_line = TRUE; /* Need to adjust #line */
+ }
+ goto end_line;
+ default: /* Not a comment */
+not_comment:
+ *tp++ = '/';
+ sp--; /* To re-read */
+ break;
+ }
+ break;
+ case '\r': /* Vertical white spaces*/
+ /* Note that [CR+LF] is already converted to [LF]. */
+ case '\f':
+ case '\v':
+ if (warn_level & 4)
+ cwarn( "Converted %.0s0x%02lx to a space" /* _W4_ */
+ , 0, (long) c, 0);
+ case '\t': /* Horizontal space */
+ case ' ':
+ if (mcpp_mode == OLD_PREP) {
+ if ((*(tp - 1) != ' ' && *(tp - 1) != COM_SEP))
+ *(tp - 1) = ' '; /* Squeeze COM_SEP with spaces */
+ } else {
+ if (*(tp - 1) != ' ')
+ *tp++ = ' '; /* Squeeze white spaces */
+ }
+ break;
+ case '"': /* String literal */
+ case '\'': /* Character constant */
+ infile->bptr = sp;
+ if (standard) {
+ tp = scan_quote( c, tp, limit, TRUE);
+ } else {
+ in_string = TRUE; /* Enable line splicing by scan_quote() */
+ tp = scan_quote( c, tp, limit, TRUE); /* (not by get_ch())*/
+ in_string = FALSE;
+ }
+ if (tp == 0) {
+ ACE_OS::free( temp); /* Unbalanced quotation */
+ return parse_line(); /* Skip the line */
+ }
+ sp = infile->bptr;
+ break;
+ default:
+ if (ACE_OS::ace_iscntrl( c)) {
+ cerror( /* Skip the control character */
+ "Illegal control character %.0s0x%lx, skipped the character" /* _E_ */
+ , 0, (long) c, 0);
+ } else { /* Any valid character */
+ *tp++ = c;
+ }
+ break;
+ }
+
+ if (limit < tp) {
+ *tp = EOS;
+ cfatal( "Too long line spliced by comments" /* _F_ */
+ , 0, 0L, 0);
+ }
+ }
+
+end_line:
+ if (temp < tp && *(tp - 1) == ' ')
+ tp--; /* Remove trailing white space */
+ *tp++ = '\n';
+ *tp = EOS;
+ infile->bptr = ACE_OS::strcpy( infile->buffer, temp); /* Write back to buffer */
+ ACE_OS::free( temp);
+ if (macro_line != 0 && macro_line != MACRO_ERROR) { /* Expanding macro */
+ temp = infile->buffer;
+ if (*temp == ' ')
+ temp++;
+ if (*temp == '#'
+ || (mcpp_mode == STD && *temp == '%' && *(temp + 1) == ':'))
+ if (warn_level & 1)
+ cwarn(
+ "Macro started at line %.0s%ld swallowed directive-like line" /* _W1_ */
+ , 0, macro_line, 0);
+ }
+ return infile->buffer;
+}
+
+static char * read_a_comment(
+ char * sp
+)
+/*
+ * Read over a comment (which may cross the lines).
+ */
+{
+ int c;
+
+ if (keep_comments) /* If writing comments */
+ mcpp_fputs( "/*", OUT); /* Write the initializer*/
+ c = *sp++;
+
+ while (1) { /* Eat a comment */
+ if (keep_comments)
+ mcpp_fputc( c, OUT);
+
+ switch (c) {
+ case '/':
+ if ((c = *sp++) != '*') /* Don't let comments */
+ continue; /* nest. */
+ if (warn_level & 1)
+ cwarn( "\"/*\" within comment", 0, 0L, 0); /* _W1_ */
+ if (keep_comments)
+ mcpp_fputc( c, OUT);
+ /* Fall into * stuff */
+ case '*':
+ if ((c = *sp++) != '/') /* If comment doesn't */
+ continue; /* end, look at next. */
+ if (keep_comments) { /* Put out comment */
+ mcpp_fputc( c, OUT); /* terminator, too. */
+ mcpp_fputc( '\n', OUT); /* Newline to avoid mess*/
+ }
+ return sp; /* End of comment */
+ case '\n':
+ if (! keep_comments) /* We'll need a #line */
+ wrong_line = TRUE; /* later... */
+ if ((sp = get_line( TRUE)) == 0) /* End of file */
+ return 0; /* within comment */
+ break;
+ default: /* Anything else is */
+ break; /* just a character */
+ } /* End switch */
+
+ c = *sp++;
+ } /* End comment loop */
+
+ return sp; /* Never reach here */
+}
+
+static char * mcpp_fgets(
+ char * s,
+ int size,
+ FILE * stream
+)
+{
+ return ACE_OS::fgets( s, size, stream);
+}
+
+static char * get_line(
+ int in_comment
+)
+/*
+ * ANSI (ISO) C: translation phase 1, 2.
+ * Get the next logical line from source file.
+ * Convert [CR+LF] to [LF].
+ */
+{
+#if COMPILER == INDEPENDENT
+#define cr_warn_level 1
+#else
+#define cr_warn_level 2
+#endif
+ static int cr_converted;
+ int converted = FALSE;
+ int len; /* Line length - alpha */
+ char * ptr;
+
+ if (infile == 0) /* End of a source file */
+ return 0;
+ ptr = infile->bptr = infile->buffer;
+
+ while (mcpp_fgets( ptr, (int) (infile->buffer + NBUFF - ptr), infile->fp)
+ != 0) {
+ /* Translation phase 1 */
+ src_line++; /* Gotten next physical line */
+ if (standard && src_line == line_limit + 1 && (warn_level & 1))
+ cwarn( "Line number %.0s\"%ld\" got beyond range" /* _W1_ */
+ , 0, src_line, 0);
+ if (mcpp_debug & (TOKEN | GETC)) { /* Dump it to DBG */
+ mcpp_fprintf( DBG, "\n#line %ld (%s)", src_line, cur_fullname);
+ dump_string( 0, ptr);
+ }
+ len = ACE_OS::strlen( ptr);
+ if (NBUFF - 1 <= ptr - infile->buffer + len
+ && *(ptr + len - 1) != '\n') {
+ if (NBUFF - 1 <= len)
+ cfatal( "Too long source line" /* _F_ */
+ , 0, 0L, 0);
+ else
+ cfatal( "Too long logical line" /* _F_ */
+ , 0, 0L, 0);
+ }
+ if (*(ptr + len - 1) != '\n') /* Unterminated source line */
+ break;
+ if (len >= 2 && *(ptr + len - 2) == '\r') { /* [CR+LF] */
+ *(ptr + len - 2) = '\n';
+ *(ptr + --len) = EOS;
+ if (! cr_converted && (warn_level & cr_warn_level)) {
+ cwarn( "Converted [CR+LF] to [LF]" /* _W1_ _W2_ */
+ , 0, 0L, 0);
+ cr_converted = TRUE;
+ }
+ }
+ if (standard) {
+ if (trig_flag)
+ converted = cnv_trigraph( ptr);
+ if (mcpp_mode == POST_STD && dig_flag)
+ converted += cnv_digraph( ptr);
+ if (converted)
+ len = ACE_OS::strlen( ptr);
+ /* Translation phase 2 */
+ len -= 2;
+ if (len >= 0) {
+ if ((*(ptr + len) == '\\') && ! last_is_mbchar( ptr, len)) {
+ /* <backslash><newline> (not MBCHAR) */
+ ptr = infile->bptr += len; /* Splice the lines */
+ wrong_line = TRUE;
+ continue;
+ }
+ }
+#if NBUFF-2 > SLEN90MIN
+ if (ptr - infile->buffer + len + 2 > str_len_min + 1
+ && (warn_level & 4)) /* +1 for '\n' */
+ cwarn( "Logical source line longer than %.0s%ld bytes" /* _W4_ */
+ , 0, str_len_min, 0);
+#endif
+ }
+ return infile->bptr = infile->buffer; /* Logical line */
+ }
+
+ /* End of a (possibly included) source file */
+ if (ferror( infile->fp))
+ cfatal( "File read error", 0, 0L, 0); /* _F_ */
+ at_eof( in_comment); /* Check at end of file */
+ if (zflag) {
+ no_output--; /* End of included file */
+ keep_comments = cflag && compiling && !no_output;
+ }
+ return 0;
+}
+
+#define TRIOFFSET 10
+
+int cnv_trigraph(
+ char * in
+)
+/*
+ * Perform in-place trigraph replacement on a physical line. This was added
+ * to the C90. In an input text line, the sequence ??[something] is
+ * transformed to a character (which might not appear on the input keyboard).
+ */
+{
+ const char * const tritext = "=(/)'<!>-\0#[\\]^{|}~";
+ /* ^ ^
+ * +----------+
+ * this becomes this
+ */
+ int count = 0;
+ const char * tp;
+
+ while ((in = ACE_OS::strchr( in, '?')) != 0) {
+ if (*++in != '?')
+ continue;
+ while (*++in == '?')
+ ;
+ if ((tp = ACE_OS::strchr( tritext, *in)) == 0)
+ continue;
+ in[ -2] = tp[ TRIOFFSET];
+ in--;
+ ACE_OS::memmove( in, in + 2, ACE_OS::strlen( in + 1));
+ count++;
+ }
+
+ if (count && (warn_level & 16))
+ cwarn( "%.0s%ld trigraph(s) converted" /* _W16_ */
+ , 0, (long) count, 0);
+ return count;
+}
+
+int cnv_digraph(
+ char * in
+)
+/*
+ * Perform in-place digraph replacement on a physical line.
+ * Called only in POST_STD mode.
+ */
+{
+ int count = 0;
+ int i;
+ int c1, c2;
+
+ while ((i = ACE_OS::strcspn( in, "%:<")), (c1 = in[ i]) != '\0') {
+ in += i + 1;
+ c2 = *in;
+ switch (c1) {
+ case '%' :
+ switch (c2) {
+ case ':' : *(in - 1) = '#'; break;
+ case '>' : *(in - 1) = '}'; break;
+ default : continue;
+ }
+ break;
+ case ':' :
+ switch (c2) {
+ case '>' : *(in - 1) = ']'; break;
+ default : continue;
+ }
+ break;
+ case '<' :
+ switch (c2) {
+ case '%' : *(in - 1) = '{'; break;
+ case ':' : *(in - 1) = '['; break;
+ default : continue;
+ }
+ break;
+ }
+ ACE_OS::memmove( in, in + 1, ACE_OS::strlen( in));
+ count++;
+ }
+
+ if (count && (warn_level & 16))
+ cwarn( "%.0s%ld digraph(s) converted" /* _W16_ */
+ , 0, (long) count, 0);
+ return count;
+}
+
+static int last_is_mbchar(
+ const char * in, /* Input physical line */
+ int len /* Length of the line minus 2 */
+)
+/*
+ * Return 2, if the last char of the line is second byte of SJIS or BIGFIVE,
+ * else return 0.
+ */
+{
+ const char * cp = in + len;
+ const char * const endp = in + len; /* -> the char befor '\n' */
+
+ if ((mbchar & (SJIS | BIGFIVE)) == 0)
+ return 0;
+ while (in <= --cp) { /* Search backwardly */
+ if ((char_type[ *cp & UCHARMAX] & mbstart) == 0)
+ break; /* Not the first byte of MBCHAR */
+ }
+ if ((endp - cp) & 1)
+ return 0;
+ else
+ return 2;
+}
+
+static void at_eof(
+ int in_comment
+)
+/*
+ * Check the partial line, unterminated comment, unbalanced #if block,
+ * uncompleted macro call at end of file or at end of input.
+ */
+{
+ const char * const format
+ = "End of %s with %.0ld%s"; /* _E_ _W1_ */
+ const char * const unterm_if_format
+= "End of %s within #if (#ifdef) section started at line %ld"; /* _E_ _W1_ */
+ const char * const unterm_macro_format
+ = "End of %s within macro call started at line %ld";/* _E_ _W1_ */
+ const char * const input
+ = infile->parent ? "file" : "input"; /* _E_ _W1_ */
+ const char * const no_newline
+ = "no newline, supplemented newline"; /* _W1_ */
+ const char * const unterm_com
+ = "unterminated comment, terminated the comment"; /* _W1_ */
+ const char * const backsl = "\\, deleted the \\"; /* _W1_ */
+ const char * const unterm_asm_format
+= "End of %s with unterminated #asm block started at line %ld"; /* _E_ _W1_ */
+ size_t len;
+ char * cp = infile->buffer;
+ IFINFO * ifp;
+
+ len = ACE_OS::strlen( cp);
+ if (len && *(cp += (len - 1)) != '\n') {
+ *++cp = '\n'; /* Supplement <newline> */
+ *++cp = EOS;
+ if (standard && (warn_level & 1))
+ cwarn( format, input, 0L, no_newline);
+ else if (mcpp_mode == KR && (warn_level & 1))
+ cwarn( format, input, 0L, no_newline);
+ }
+ if (standard && infile->buffer < infile->bptr) {
+ cp += len - 2;
+ *cp++ = '\n'; /* Delete the \\ */
+ *cp = EOS;
+ if (warn_level & 1)
+ cwarn( format, input, 0L, backsl);
+ }
+ if (in_comment) {
+ if ((standard || mcpp_mode == KR) && (warn_level & 1))
+ cwarn( format, input, 0L, unterm_com);
+ }
+
+ if (infile->initif < ifptr) {
+ ifp = infile->initif + 1;
+ if (standard) {
+ cerror( unterm_if_format, input, ifp->ifline, 0);
+ ifptr = infile->initif; /* Clear information of */
+ compiling = ifptr->stat; /* erroneous grouping */
+ } else if (mcpp_mode != OLD_PREP && (warn_level & 1)) {
+ cwarn( unterm_if_format, input, ifp->ifline, 0);
+ }
+ }
+
+ if (macro_line != 0 && macro_line != MACRO_ERROR
+ && ((mcpp_mode == STD && in_getarg) || ! standard)) {
+ if (standard) {
+ cerror( unterm_macro_format, input, macro_line, 0);
+ macro_line = MACRO_ERROR;
+ } else if (warn_level & 1) {
+ cwarn( unterm_macro_format, input, macro_line, 0);
+ }
+ }
+
+ if (in_asm && mcpp_mode == KR && (warn_level & 1))
+ cwarn( unterm_asm_format, input, in_asm, 0);
+}
+
+void unget_ch( void)
+/*
+ * Back the pointer to reread the last character. Fatal error (code bug)
+ * if we back too far. unget_ch() may be called, without problems, at end of
+ * file. Only one character may be ungotten. If you need to unget more,
+ * call unget_string().
+ */
+{
+ if (in_token) {
+ infile->bptr--;
+ return;
+ }
+
+ if (infile != 0) {
+ if (mcpp_mode == POST_STD && infile->fp) {
+ switch (insert_sep) {
+ case INSERTED_SEP: /* Have just read an inserted separator */
+ insert_sep = INSERT_SEP;
+ return;
+ case INSERT_SEP:
+ cfatal( "Bug: unget_ch() just after scan_token()" /* _F_ */
+ , 0, 0L, 0);
+ break;
+ default:
+ break;
+ }
+ }
+ --infile->bptr;
+ if (infile->bptr < infile->buffer) /* Shouldn't happen */
+ cfatal( "Bug: Too much pushback", 0, 0L, 0); /* _F_ */
+ }
+
+ if (mcpp_debug & GETC)
+ dump_unget( "after unget");
+}
+
+FILEINFO * unget_string(
+ const char * text, /* Text to unget */
+ const char * name /* Name of the macro */
+)
+/*
+ * Push a string back on the input stream. This is done by treating
+ * the text as if it were a macro.
+ */
+{
+ FILEINFO * file;
+ size_t size;
+
+ if (text)
+ size = ACE_OS::strlen( text) + 1;
+ else
+ size = 1;
+ file = get_file( name, size);
+ if (text)
+ ACE_OS::memcpy( file->buffer, text, size);
+ else
+ *file->buffer = EOS;
+ return file;
+}
+
+char * save_string(
+ const char * text
+)
+/*
+ * Store a string into free memory.
+ */
+{
+ char * result;
+ size_t size;
+
+ size = ACE_OS::strlen( text) + 1;
+ result = xmalloc( size);
+ ACE_OS::memcpy( result, text, size);
+ return result;
+}
+
+FILEINFO * get_file(
+ const char * name, /* File or macro name string */
+ size_t bufsize /* Line buffer size */
+)
+/*
+ * Common FILEINFO buffer initialization for a new file or macro.
+ */
+{
+ FILEINFO * file;
+
+ file = (FILEINFO *) xmalloc( sizeof (FILEINFO));
+ file->buffer = xmalloc( bufsize);
+ file->bptr = file->buffer; /* Initialize line ptr */
+ file->buffer[ 0] = EOS; /* Force first read */
+ file->line = 0L; /* (Not used just yet) */
+ file->fp = 0; /* No file yet */
+ file->pos = 0L; /* No pos to remember */
+ file->parent = infile; /* Chain files together */
+ file->initif = ifptr; /* Initial ifstack */
+ file->dirp = 0; /* No sys-header yet */
+ file->real_fname = name; /* Save file/macro name */
+ if (name) {
+ file->filename = xmalloc( ACE_OS::strlen( name) + 1);
+ ACE_OS::strcpy( file->filename, name); /* Copy for #line */
+ } else {
+ file->filename = 0;
+ }
+#if MCPP_LIB
+ file->last_fputc = mcpp_lib_fputc;
+ file->last_fputs = mcpp_lib_fputs;
+ file->last_fprintf = mcpp_lib_fprintf;
+#endif
+ if (infile != 0) { /* If #include file */
+ infile->line = src_line; /* Save current line */
+#if MCPP_LIB
+ infile->last_fputc = mcpp_fputc;
+ infile->last_fputs = mcpp_fputs;
+ infile->last_fprintf = mcpp_fprintf;
+#endif
+ }
+ infile = file; /* New current file */
+ return file; /* All done. */
+}
+
+static const char * const out_of_memory
+ = "Out of memory (required size is %.0s0x%lx bytes)"; /* _F_ */
+
+char *
+(xmalloc)(
+ size_t size
+)
+/*
+ * Get a block of free memory.
+ */
+{
+ char * result;
+
+ if ((result = (char *) ACE_OS::malloc( size)) == 0) {
+ if (mcpp_debug & MEMORY)
+ print_heap();
+ cfatal( out_of_memory, 0, (long) size, 0);
+ }
+ return result;
+}
+
+char * (xrealloc)(
+ char * ptr,
+ size_t size
+)
+/*
+ * Reallocate ACE_OS::malloc()ed memory.
+ */
+{
+ char * result;
+
+ if ((result = (char *) ACE_OS::realloc( ptr, size)) == 0 && size != 0) {
+ /* 'size != 0' is necessary to cope with some */
+ /* implementation of realloc( ptr, 0) which returns 0. */
+ if (mcpp_debug & MEMORY)
+ print_heap();
+ cfatal( out_of_memory, 0, (long) size, 0);
+ }
+ return result;
+}
+
+static void put_line(
+ char * out,
+ FILE * fp
+)
+/*
+ * Put out a logical source line.
+ * This routine is called only in OLD_PREP mode.
+ */
+{
+ int c;
+
+ while ((c = *out++) != EOS) {
+ if (c != COM_SEP) /* Skip 0-length comment */
+ mcpp_fputc( c, FP2DEST( fp));
+ }
+}
+
+static void do_msg(
+ const char * severity, /* "fatal", "error", "warning" */
+ const char * format, /* Format for the error message */
+ const char * arg1, /* String arg. for the message */
+ long arg2, /* Integer argument */
+ const char * arg3 /* Second string argument */
+)
+/*
+ * Print filenames, macro names, line numbers and error messages.
+ */
+{
+#define MAX_MACRO_FILE 4
+
+ FILEINFO * file;
+ DEFBUF * defp;
+ int i;
+ size_t slen;
+ const char * arg_s[ 2];
+ char * arg_t[ 2];
+ char * tp;
+ const char * sp;
+ int c;
+ int ind;
+
+ ACE_OS::fflush( fp_out); /* Synchronize output and diagnostics */
+ arg_s[ 0] = arg1; arg_s[ 1] = arg3;
+
+ for (i = 0; i < 2; i++) { /* Convert special characters to visible */
+ sp = arg_s[ i];
+ if (sp != 0)
+ slen = ACE_OS::strlen( sp) + 1;
+ else
+ slen = 1;
+ tp = arg_t[ i] = (char *) ACE_OS::malloc( slen);
+ /* Don't use xmalloc() so as not to cause infinite recursion */
+ if (sp == 0 || *sp == EOS) {
+ *tp = EOS;
+ continue;
+ }
+
+ while ((c = *sp++) != EOS) {
+ switch (c) {
+ case TOK_SEP:
+ if (mcpp_mode == OLD_PREP) /* COM_SEP */
+ break; /* Skip magic characters */
+ /* Else fall through */
+ case RT_END:
+ case IN_SRC:
+ if (mcpp_mode != STD) {
+ *tp++ = ' ';
+ /* Illegal control character, convert to a space*/
+ break;
+ } /* Else fall through */
+ case CAT:
+ case ST_QUOTE:
+ case DEF_MAGIC:
+ if (! standard)
+ *tp++ = ' ';
+ break; /* Skip magic characters */
+ case '\n':
+ *tp++ = ' '; /* Convert '\n' to a space */
+ break;
+ default:
+ *tp++ = c;
+ break;
+ }
+ }
+
+ if (*(sp - 2) == '\n')
+ tp--;
+ *tp = EOS;
+ }
+
+ /* Print diagnostic */
+ file = infile;
+ while (file != 0 && (file->fp == 0 || file->fp == (FILE *)-1))
+ file = file->parent; /* Skip macro */
+ if (file != 0) {
+ file->line = src_line;
+ mcpp_fprintf( ERR, "%s:%ld: %s: ", cur_fullname, src_line, severity);
+ }
+ mcpp_fprintf( ERR, format, arg_t[ 0], arg2, arg_t[ 1]);
+ mcpp_fputc( '\n', ERR);
+ if (no_source_line)
+ goto free_arg;
+
+ /* Print source line, includers and expanding macros */
+ file = infile;
+ if (file != 0 && file->fp != 0) {
+ if (mcpp_mode == OLD_PREP) {
+ mcpp_fputs( " ", ERR);
+ put_line( file->buffer, fp_err);
+ } else {
+ mcpp_fprintf( ERR, " %s", file->buffer);
+ /* Current source line */
+ }
+ file = file->parent;
+ }
+ while (file != 0) { /* Print #includes, too */
+ if (file->fp == 0) { /* Macro */
+ if (file->filename) {
+ defp = look_id( file->filename);
+ if (defp->nargs >= DEF_NOARGS - 2)
+ dump_a_def( " macro", defp, FALSE, FALSE, TRUE, fp_err);
+ }
+ } else { /* Source file */
+ if (file->buffer[ 0] == '\0')
+ ACE_OS::strcpy( file->buffer, "\n");
+ if (mcpp_mode != OLD_PREP) {
+ mcpp_fprintf( ERR, " from %s%s: %ld: %s",
+ *(file->dirp), /* Include directory */
+ file->real_fname, /* Current file name */
+ file->line, /* Current line number */
+ file->buffer); /* The source line */
+ } else {
+ mcpp_fprintf( ERR, " from %s%s: %ld: ",
+ *(file->dirp), file->real_fname, file->line);
+ put_line( file->buffer, fp_err);
+ }
+ }
+ file = file->parent;
+ }
+
+ if (! macro_name)
+ goto free_arg;
+ /* Additional information of macro definitions */
+ expanding_macro[ 0].name = macro_name;
+ for (ind = 0; ind <= exp_mac_ind; ind++) {
+ int ind_done;
+ FILEINFO * file;
+
+ for (ind_done = 0; ind_done < ind; ind_done++)
+ if (str_eq( expanding_macro[ ind].name
+ , expanding_macro[ ind_done].name))
+ break; /* Already reported */
+ if (ind_done < ind)
+ continue;
+ for (file = infile; file; file = file->parent)
+ if (file->fp == 0 && file->filename
+ && str_eq( expanding_macro[ ind].name, file->filename))
+ break; /* Already reported */
+ if (file)
+ continue;
+ if ((defp = look_id( expanding_macro[ ind].name)) != 0) {
+ if (defp->nargs < DEF_NOARGS - 2)
+ continue; /* __FILE__, __LINE__ */
+ dump_a_def( " macro", defp, FALSE, FALSE, TRUE, fp_err);
+ /* Macro already read over */
+ }
+ }
+
+free_arg:
+ for (i = 0; i < 2; i++)
+ ACE_OS::free( arg_t[ i]);
+}
+
+void cfatal(
+ const char * format,
+ const char * arg1,
+ long arg2,
+ const char * arg3
+)
+/*
+ * A real disaster.
+ */
+{
+ do_msg( "fatal error", format, arg1, arg2, arg3);
+ longjmp( error_exit, -1);
+}
+
+void cerror(
+ const char * format,
+ const char * arg1,
+ long arg2,
+ const char * arg3
+)
+/*
+ * Print a error message.
+ */
+{
+ do_msg( "error", format, arg1, arg2, arg3);
+ errors++;
+}
+
+void cwarn(
+ const char * format,
+ const char * arg1,
+ long arg2,
+ const char * arg3
+)
+/*
+ * Maybe an error.
+ */
+{
+ do_msg( "warning", format, arg1, arg2, arg3);
+}
+
+void dump_string(
+ const char * why,
+ const char * text
+)
+/*
+ * Dump text readably.
+ * Bug: macro argument number may be putout as a control character or any
+ * other character, just after MAC_PARM has been read away.
+ */
+{
+ const char * cp;
+ const char * chr;
+ int c;
+
+ if (why != 0)
+ mcpp_fprintf( DBG, " (%s)", why);
+ mcpp_fputs( " => ", DBG);
+
+ if (text == 0) {
+ mcpp_fputs( "0", DBG);
+ return;
+ }
+
+ for (cp = text; (c = *cp++ & UCHARMAX) != EOS; ) {
+ chr = 0;
+
+ switch (c) {
+ case MAC_PARM:
+ c = *cp++ & UCHARMAX;
+ mcpp_fprintf( DBG, "<%d>", c);
+ break;
+ case DEF_MAGIC:
+ if (standard) {
+ chr = "<MAGIC>";
+ break;
+ } /* Else fall through */
+ case CAT:
+ if (standard) {
+ chr = "##";
+ break;
+ } /* Else fall through */
+ case ST_QUOTE:
+ if (standard) {
+ chr = "#";
+ break;
+ } /* Else fall through */
+ case RT_END:
+ if (standard) {
+ chr = "<RT_END>";
+ break;
+ } /* Else fall through */
+ case IN_SRC:
+ if (standard) {
+ chr = "<SRC>";
+ break;
+ } else { /* Control character */
+ mcpp_fprintf( DBG, "<^%c>", c + '@');
+ }
+ case TOK_SEP:
+ if (mcpp_mode == STD) {
+ chr = "<TSEP>";
+ break;
+ } else if (mcpp_mode == OLD_PREP) { /* COM_SEP */
+ chr = "<CSEP>";
+ break;
+ } /* Else fall through */
+ default:
+ if (c < ' ')
+ mcpp_fprintf( DBG, "<^%c>", c + '@');
+ else
+ mcpp_fputc( c, DBG);
+ break;
+ }
+
+ if (chr)
+ mcpp_fputs( chr, DBG);
+ }
+
+ mcpp_fputc( '\n', DBG);
+}
+
+void dump_unget(
+ const char * why
+)
+/*
+ * Dump all ungotten junk (pending macros and current input lines).
+ */
+{
+ const FILEINFO * file;
+
+ mcpp_fputs( "dump of pending input text", DBG);
+ if (why != 0) {
+ mcpp_fputs( "-- ", DBG);
+ mcpp_fputs( why, DBG);
+ }
+ mcpp_fputc( '\n', DBG);
+
+ for (file = infile; file != 0; file = file->parent)
+ dump_string( file->real_fname ? file->real_fname
+ : file->filename ? file->filename : "0", file->bptr);
+}
+
+static void dump_token(
+ int token_type,
+ const char * cp /* Token */
+)
+/*
+ * Dump a token.
+ */
+{
+ static const char * const t_type[]
+ = { "NAM", "NUM", "STR", "WSTR", "CHR", "WCHR", "OPE", "SPE"
+ , "SEP", };
+
+ mcpp_fputs( "token", DBG);
+ dump_string( t_type[ token_type - NAM], cp);
+}
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/system.H b/TAO/TAO_IDL/contrib/mcpp/system.H
new file mode 100644
index 00000000000..1b12cb61ce2
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/system.H
@@ -0,0 +1,387 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * S Y S T E M . H
+ * S y s t e m D e p e n d e n t
+ * D e f i n i t i o n s f o r M C P P
+ *
+ * Definitions in this file may be edited to configure MCPP for particular
+ * operating systems and compiler configurations.
+ *
+ * Note: MCPP assumes the system implement the Ascii character set.
+ * If this is not the case, you will have to do some editing here and there.
+ */
+
+#define SYSTEM_H
+
+#if HAVE_CONFIG_H
+#include "configed.H"
+#else
+#include "noconfig.H"
+#endif
+
+#include "ace/Basic_Types.h"
+#include "ace/OS_NS_string.h"
+
+/* Some system has a wrong definition of UCHAR_MAX. See cpp-test.html#5.1.3 */
+#if UCHARMAX < -255
+#error "The definition of UCHARMAX (possibly UCHAR_MAX too) is wrong. Define it as signed int value as 255, not as unsigned value as 255U."
+#endif
+
+/*
+ * PART 1 and PART 2 are defined in the above header files.
+ */
+
+/*
+ * P A R T 1 Configurations for target-operating-system
+ * and target-compiler.
+ */
+
+/*
+ * P A R T 2 Configurations for host-compiler.
+ */
+
+/*
+ * P A R T 3 Configurations for default settings, typedefs and
+ * translation limits.
+ */
+
+/*
+ * The variable 'mcpp_mode' specifies the mode of preprocessing as one of
+ * OLD_PREP, KR, STD, or POST_STD.
+ * Those modes have many differences each other --
+ * i.e. handling of translation phases; handling of some
+ * preprocessing tokens; availability of some directives; way of
+ * macro expansion;
+ * -- as follows.
+ *
+ * KR Actual arguments of a macro are expanded (after substitution)
+ * with rest of the replacement text and the subsequent source text.
+ * ## in macro definition has no significance to cpp. The surrounding
+ * tokens are macro-expanded separately. Also, # has no significance
+ * to cpp. The following token is expanded.
+ * Directly or intermediately recursive macro call causes an error.
+ * <backslash><newline> sequence is deleted only in string literals
+ * and in #define directive lines.
+ * sizeof (type) can be used in #if line.
+ * KR corresponds to the "K&R 1st."
+ *
+ * OLD_PREP In addition to the KR specifications, this mode has the
+ * following characteristics (and some others).
+ * Converts comment to 0 space instead of 1 space.
+ * Expands the parameter like spelling in string literal as a macro.
+ * Does not check unmatched pair of '"' or '\''.
+ * OLD_PREP corresponts to "Reiser model" cpp.
+ *
+ * STD Standard conforming mode.
+ * <backslash><newline> sequence is always deleted after trigraph
+ * conversion and before tokenization.
+ * Digraph sequences are recognized as tokens.
+ * Actual arguments of a macro are expanded separately prior to
+ * re-scanning of the replacement text.
+ * The name in the replacement text once expanded is not re-expanded,
+ * thus preventing recursive death.
+ * ## in macro definition concatenates tokens. The tokens are not
+ * expanded. The concatenated token is expanded by rescanning.
+ * # in macro definition stringizes the following argument. The argument
+ * is not expanded. \ is inserted before " and \ in or surrounding
+ * the string literal or character constant.
+ * An expanded macro is surrounded by spaces to prevent unintended
+ * token merging.
+ *
+ * POST_STD This mode simplifies the behavior of STD mode as follows.
+ * 1. Digraph sequences are converted in translation phase 1, as
+ * alternate characters rather than as tokens.
+ * 2. A space is inserted as a token separator between any tokens in
+ * a source (except a macro name and the next '(' in macro
+ * definition): thus simplifying tokenization, test of macro
+ * redefinition and macro expansion especially "stringization".
+ * 3. Test of macro redefinition ignores difference of parameter names,
+ * test of which has little utility and not a little overhead.
+ * 4. #if expression forbids character constants, which have little
+ * portability, little utility and not a little overhead.
+ * 5. Rescanning of a macro expansion is limited in the replacement
+ * text, rest of the source file is not scanned, thus making the
+ * syntax of "function-like" macro call more similar to that of
+ * function call.
+ * 6. Argument of #include directive in <header.h> form is an obsolescent
+ * feature.
+ * 7. '$' or so are not treated specially in #define directive.
+ * 8. Trigraphs, UCN (universal-character name) are not recognized.
+ * 9. Multi-byte characters in an identifier are not recognized.
+ *
+ * The following specifications are available when mode is STD or POST_STD.
+ * preprocessing number token, digraphs,
+ * #pragma (#pragma MCPP put_defines, #pragma MCPP warning
+ * , #pragma MCPP debug) directive,
+ * #error directive,
+ * #if defined operator, #elif directive,
+ * predefined macros __FILE__, __LINE__, __DATE__, __TIME__
+ * , __STDC__, __STDC_VERSION__, __STDC_HOSTED__,
+ * wide character constant, wide character string literal,
+ * _Pragma() operator, variable-arguments macro,
+ * macro as an argument of #include, #line directives,
+ * escape sequences \x[hex-digits], \a, \v,
+ * '+' option (C++ preprocessing),
+ * 'S<n>' option (re-defines __STDC__ as <n>, unpredefine some macros),
+ * 'V<n>' option (re-defines __STDC_VERSION__ or __cplusplus as <n>),
+ * 'h<n>' option (re-defines __STDC_HOSTED__ as <n>).
+ * The following specifications are available only in STD mode.
+ * Trigraphs and UCN,
+ * Multi-byte characters in an identifier.
+ * The following specifications are available only in KR and OLD_PREP modes.
+ * #assert, #asm, #endasm, #put_defines, #debug and some other older
+ * directives,
+ * argument of #line directive other than dicimal-digits.
+ */
+
+/* The values of 'mcpp_mode'. */
+#define OLD_PREP 1 /* "Reiser" cpp mode */
+#define KR 2 /* K&R 1st mode */
+#define STD 3 /* Standard moce */
+#define POST_STD 9 /* Special mode of MCPP */
+
+/*
+ * TRIGRAPHS_INIT Initial value for the -3 option. If TRUE -3
+ * disables trigraphs, if FALSE -3 enables them.
+ * DIGRAPHS_INIT Initial value for the -2 option. If TRUE -2
+ * disables digraphs, if FALSE -2 enables them.
+ * OK_UCN Enable recognition of Universal-Character-Name sequence
+ * by -V199901L option.
+ * OK_MBIDENT Enable multi-byte characters in identifier by -V199901L
+ * option.
+ * EXPAND_PRAGMA Enable macro expansion of #pragma line (even in modes
+ * other than C99).
+ * expr_t, uexpr_t Type of maximum integer:
+ * long long (unsigned long long) or longer.
+ * EXPR_MAX should be defined to the maximum value of uexpr_t.
+ */
+#define TRIGRAPHS_INIT FALSE
+#define DIGRAPHS_INIT FALSE
+#ifndef EXPAND_PRAGMA
+#define EXPAND_PRAGMA FALSE
+#endif
+#define OK_UCN TRUE
+#define OK_MBIDENT FALSE
+
+typedef ACE_INT64 expr_t;
+typedef ACE_UINT64 uexpr_t;
+
+#define EXPR_MAX ACE_INT64_MAX
+#if 0
+#if HAVE_INTMAX_T
+#define EXPR_MAX UINT_MAX
+#elif HAVE_LONG_LONG
+#if (HOST_COMPILER == MSC && _MSC_VER < 1400) || HOST_COMPILER == BORLANDC
+#define EXPR_MAX 0xFFFFFFFFFFFFFFFFui64
+#else
+#define EXPR_MAX 0xFFFFFFFFFFFFFFFFULL
+#endif
+#else
+#define EXPR_MAX 4294967295UL
+#endif
+#endif
+
+/*
+ * DOLLAR_IN_NAME Should be set TRUE if $ is a valid letter in identifiers
+ * or FALSE if $ is invalid.
+ */
+#ifndef DOLLAR_IN_NAME
+#define DOLLAR_IN_NAME FALSE
+#endif
+
+/*
+ * Translation limits.
+ * The following definitions are used to allocate memory for work buffers.
+ *
+ * NWORK Output buffer size. Set this size according to your compiler-
+ * proper. Length of string literal should be less than NWORK
+ * - 1.
+ * NBUFF Input buffer size after line concatenation by <backslash>
+ * <newline>.
+ * NMACWORK Internal work buffer size for macro definition and expansion.
+ * IDMAX The longest identifier length.
+ * NMACPARS The maximum number of #define parameters.
+ * NOTE: Must be NMACPARS <= UCHARMAX.
+ * NEXP The maximum nesting depth of #if expressions.
+ * BLK_NEST The number of nested #if's permitted.
+ * NINCLUDE The number of directories that may be specified on a per-
+ * system basis, or by the -I option.
+ * RESCAN_LIMIT The maximum rescan times of macro expansion in STD or POST_STD
+ * modes.
+ * PRESTD_RESCAN_LIMIT The maximum rescan times of macro expansion in KR or
+ * OLD_PREP modes..
+ *
+ * NBUFF should not be smaller than NWORK.
+ * NMACWORK should not be smaller than NWORK * 2.
+ *
+ * SBSIZE defines the number of hash-table slots for the macro symbol table.
+ * It must be a power of 2.
+ *
+ * MKDEP_MAX The maximum number of filenames in a dependency line of
+ * output of -M* option.
+ */
+
+#ifndef IDMAX
+#define IDMAX 0x400
+#endif
+#ifndef NMACPARS
+#define NMACPARS 0xFF
+#endif
+#ifndef NEXP
+#define NEXP 0x100
+#endif
+#ifndef BLK_NEST
+#define BLK_NEST 0x100
+#endif
+#ifndef INCLUDE_NEST
+#define INCLUDE_NEST 0x100
+#endif
+#ifndef NINCLUDE
+#define NINCLUDE 0x80
+#endif
+#ifndef RESCAN_LIMIT
+#define RESCAN_LIMIT 0x40
+#endif
+#ifndef PRESTD_RESCAN_LIMIT
+#define PRESTD_RESCAN_LIMIT 0x100
+#endif
+#ifndef NBUFF
+#define NBUFF 0x10000 /* Must be NWORK <= NBUFF */
+#endif
+#ifndef NWORK
+#define NWORK NBUFF /* 0x1000, 0x4000, 0x10000, .. */
+#endif
+#ifndef NMACWORK
+#define NMACWORK (NWORK * 4) /* Must be NWORK * 2 <= NMACWORK */
+#endif
+#ifndef SBSIZE
+#define SBSIZE 0x400
+#endif
+#ifndef MKDEP_MAX
+#define MKDEP_MAX 0x100
+#endif
+
+#if UCHARMAX < NMACPARS
+ #error "NMACPARS should not be greater than UCHARMAX"
+#endif
+
+#if NBUFF < NWORK
+ #error "NBUFF must be same or greater than NWORK"
+#endif
+#if NMACWORK < NWORK * 2
+ #error "NMACWORK must be same or greater than NWORK * 2"
+#endif
+
+#define SBMASK (SBSIZE - 1)
+#if (SBSIZE ^ SBMASK) != ((SBSIZE * 2) - 1)
+ #error "SBSIZE must be a power of 2 !"
+#endif
+
+/*
+ * Translation limits required by the Standard.
+ *
+ * *90MIN limits specified by C90.
+ * *99MIN limits specified by C99.
+ * *_CPLUS_MIN limits recommended by C++ (ISO 1998/07 Standard).
+ *
+ * SLEN*MIN Characters in a logical source line
+ * and characters in a string literal or wide string literal
+ * (after concatenation).
+ * IDLEN*MIN Significant initial characters in an internal identifier
+ * or a macro name.
+ * NMACPARS*MIN Parameters in one macro definition.
+ * Arguments in one macro invocation.
+ * EXP_NEST*MIN Nesting levels of parenthesized expressions in a full
+ * expression.
+ * BLK_NEST*MIN Nesting levels of conditional inclusion.
+ * INCLUDE_NEST*MIN Nesting levels for #include files.
+ * NMACRO*MIN Macro identifiers simultaneously defined in one translation
+ * unit.
+ */
+#define SLEN90MIN 0x1FD
+#define IDLEN90MIN 0x1F
+#define NMACPARS90MIN 0x1F
+#define EXP_NEST90MIN 0x20
+#define BLK_NEST90MIN 8
+#define INCLUDE_NEST90MIN 8
+#define NMACRO90MIN 0x400
+
+#define SLEN99MIN 0xFFF
+#define IDLEN99MIN 0x3F
+#define NMACPARS99MIN 0x7F
+#define EXP_NEST99MIN 0x3F
+#define BLK_NEST99MIN 0x3F
+#define INCLUDE_NEST99MIN 0xF
+#define NMACRO99MIN 0xFFF
+
+#define SLEN_CPLUS_MIN 0x10000
+#define IDLEN_CPLUS_MIN 0x400
+#define NMACPARS_CPLUS_MIN 0x100
+#define EXP_NEST_CPLUS_MIN 0x100
+#define BLK_NEST_CPLUS_MIN 0x100
+#define INCLUDE_NEST_CPLUS_MIN 0x100
+#define NMACRO_CPLUS_MIN 0x10000
+
+/* LINE99LIMIT means the line number limit of C99 */
+#define LINE99LIMIT 0x7FFFFFFF
+
+/*
+ * STDC This macro is used for the predefined __STDC__.
+ * (STDC >= 1) disables predefined macros not beginning with '_'.
+ * STDC_VERSION is used for the value of __STDC_VERSION__.
+ * STDC_HOSTED is used for the value of __STDC_HOSTED__.
+ */
+#if IDMAX < IDLEN90MIN || NBUFF < SLEN90MIN + 3
+ || NWORK < SLEN90MIN + 2 || NMACPARS < NMACPARS90MIN
+ || NEXP < EXP_NEST90MIN || BLK_NEST < BLK_NEST90MIN
+#define STDC 0
+#endif
+#ifndef STDC
+#define STDC 1 /* 1 : for ISO 9899:1990 or later */
+#endif
+
+#ifndef STDC_VERSION
+#define STDC_VERSION 0L /* 199409L : For conforming
+ implementation to ISO 9899:1990 / Amendment 1:1995
+ 199901L : For C99 */
+#endif
+#ifndef STDC_HOSTED
+#define STDC_HOSTED 1 /* 1 : for hosted implementation,
+ 0 : for free-standing implementation (C99 specification) */
+#endif
+
+/*
+ * CPLUS specifies the default value of the pre-defined macro __cplusplus
+ * for C++ processing.
+ * The value can be changed by -V<n> option.
+ */
+#define CPLUS 1 /* 199711L for C++ Standard */
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/system.cpp b/TAO/TAO_IDL/contrib/mcpp/system.cpp
new file mode 100644
index 00000000000..b8e67c31a11
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/system.cpp
@@ -0,0 +1,3794 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
+ * All rights reserved.
+ *
+ * Some parts of this code are derived from the public domain software
+ * DECUS cpp (1984,1985) written by Martin Minow.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * S Y S T E M . C
+ * S y s t e m D e p e n d e n t R o u t i n e s
+ *
+ * Routines dependent on character set, O.S., compiler or compiler-driver.
+ * To implement MCPP for the systems not yet implemented, you must
+ * 1. specify the constants in "configed.H" or "noconfig.H",
+ * 2. append the system-dependent routines in this file.
+ */
+#if PREPROCESSED
+#include "mcpp.H"
+#else
+#include "system.H"
+#include "internal.H"
+#include "mcpp_lib.h"
+#endif
+
+#include "ace/OS_NS_unistd.h" /* For getcwd(), readlink(), getopt() */
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/OS_NS_time.h"
+#include "ace/OS_NS_stdlib.h"
+
+#undef OUT
+
+/* Functions other than standard. */
+#if 1 // HOST_SYS_FAMILY != SYS_UNIX /* On UNIX "unistd.h" will suffice */
+//FUZZ: disable check_for_lack_ACE_OS
+extern int getopt( int argc, char * const * argv, const char * opts);
+extern int optind;
+extern char * optarg;
+//FUZZ: enable check_for_lack_ACE_OS
+#endif
+
+/*
+ * PATH_DELIM is defined for the O.S. which has single byte path-delimiter.
+ * Note: '\\' or any other character identical to second byte of MBCHAR should
+ * not be used for PATH_DELIM for convenience of path-list parsing.
+ */
+#if SYS_FAMILY == SYS_UNIX || SYS_FAMILY == SYS_WIN || SYSTEM == SYS_UNKNOWN
+#define PATH_DELIM '/'
+#define SPECIAL_PATH_DELIM FALSE
+#else
+#if SYSTEM == SYS_MAC
+#define PATH_DELIM ':' /* ?? I don't know */
+#else /* Any other path-delimiter, define by yourself */
+#endif
+#define SPECIAL_PATH_DELIM TRUE /* Any path-delimiter other than '/' */
+#endif
+
+/*
+ * OBJEXT is the suffix to denote "object" file.
+ */
+#ifndef OBJEXT
+#if SYS_FAMILY == SYS_UNIX
+#define OBJEXT "o"
+#elif SYS_FAMILY == SYS_WIN
+#define OBJEXT "obj"
+#elif 1
+/* Add here appropriate definitions for other systems. */
+#endif
+#endif
+
+static void version( void);
+ /* Print version message */
+static void usage( int opt);
+ /* Putout usage of MCPP */
+static void set_opt_list( char * optlist);
+ /* Set list of legal option chars */
+static int parse_warn_level( const char * optarg, int opt);
+ /* Parse warning level option */
+static void def_a_macro( int opt, char * def);
+ /* Do a -D option */
+static void chk_opts( int sflag, long std_val, int ansi, int trad);
+ /* Check consistency of options */
+static void init_predefines( int nflag, long std_val);
+ /* Set and unset predefined macros */
+static void init_std_defines( void);
+ /* Predefine Standard macros */
+static void set_limit( void);
+ /* Set minimum translation limits */
+static void set_pragma_op( void);
+ /* Set the _Pragma() operator */
+static char * set_files( int argc, char ** argv, char ** in_pp
+ , char ** out_pp);
+ /* Set input, output, diagnostic */
+static void set_sys_dirs( int set_cplus_dir);
+ /* Set system-specific include dirs */
+static void set_env_dirs( void);
+ /* Set user-defined include dirs */
+static void parse_env( const char * env);
+ /* Parse environment variables */
+static void set_a_dir( const char * dirname);
+ /* Append an include directory */
+static char * norm_path( const char * dir, const char * fname);
+ /* Normalize pathname to compare */
+#if SYS_FAMILY == SYS_UNIX
+static void deref_syml( char * slbuf1, char * slbuf2, char * chk_start);
+ /* Dereference symbolic linked dir */
+#endif
+#if COMPILER == GNUC
+static void init_gcc_macro( int gcc_maj_ver, int gcc_min_ver);
+ /* Predefine GCC macros */
+static void undef_gcc_macro( int clearall);
+ /* Undefine GCC predef-macros */
+static void chk_env( void);
+ /* Check the environment variables */
+#elif COMPILER == MSC
+static void init_msc_macro( int wchar_t_modified);
+ /* Predefine Visual C macros */
+#endif
+static char * md_init( const char * filename, char * output);
+ /* Initialize makefile dependency */
+static char * md_quote( char * output);
+ /* 'Quote' special characters */
+static int open_include( char * filename, int searchlocal, int next);
+ /* Open the file to include */
+static int has_directory( const char * source, char * directory);
+ /* Get directory part of fname */
+static int search_dir( char * filename, int searchlocal, int next);
+ /* Search the include directories */
+static int open_file( const char ** dirp, const char * filename
+ , int local);
+ /* Open a source file */
+static const char * set_fname( const char * filename);
+ /* Remember the source filename */
+static int is_junk( void);
+ /* The directive has trailing junk? */
+static void do_once( const char * dir, const char * filename);
+ /* Process #pragma once */
+static int included( const char * dir, const char * filename);
+ /* The file has been once included? */
+static void push_or_pop( int direction);
+ /* Push or pop a macro definition */
+static int do_prestd_directive( void);
+ /* Process pre-Standard directives */
+static void do_preprocessed( void);
+ /* Process preprocessed file */
+static int do_debug( int set);
+ /* #pragma MCPP debug, #debug */
+static void dump_path( void);
+ /* Print include search path */
+static void do_asm( int asm_start);
+ /* Process #asm, #endasm */
+
+#if SYS_FAMILY == SYS_WIN
+static char * bsl2sl( char * filename); /* Convert \ to / */
+#endif
+
+static int mb_changed = FALSE; /* Flag of -e option */
+static char cur_work_dir[ FILENAMEMAX + 1]; /* Current working directory*/
+
+/*
+ * incdir[] stores the -I directories (and the system-specific #include <...>
+ * directories). This is set by set_a_dir(). A trailing PATH_DELIM is
+ * appended if absent.
+ */
+static const char * incdir[ NINCLUDE]; /* Include directories */
+static const char ** incend = incdir; /* -> active end of incdir */
+
+/*
+ * fnamelist[] stores the souce file names opened by #include directive for
+ * debugging information.
+ */
+#define FNAMELIST (NINCLUDE * 4)
+static const char * fnamelist[ FNAMELIST]; /* Source file names */
+static const char ** fname_end = fnamelist;
+ /* -> active end of fnamelist */
+
+typedef struct inc_list { /* List of #pragma once file*/
+ struct inc_list * next; /* Next file */
+ char fname[ 1]; /* Filename */
+} INC_LIST;
+
+static INC_LIST * start_inc = NULL; /* The first file in list */
+static INC_LIST * last_inc; /* The last file in list */
+
+/*
+ * 'search_rule' holds searching rule of #include "header.h" to search first
+ * before searching user specified or system-specific include directories.
+ * 'search_rule' is initialized to SEARCH_INIT. It can be changed by -I1, -I2
+ * or -I3 option. -I1 specifies CURRENT, -I2 SOURCE and -I3 both.
+ */
+
+static int search_rule = SEARCH_INIT; /* Rule to search include file */
+
+static int dDflag = FALSE; /* Flag of -dD option (for GCC) */
+static int nflag = FALSE; /* Flag of -N (-undef) option */
+
+/* Values of mkdep. */
+#define MD_MKDEP 1 /* Output source file dependency line */
+#define MD_SYSHEADER 2 /* Print also system-header names */
+#define MD_FILE 4 /* Output to the file named *.d */
+#define MD_PHONY 8 /* Print also phony targets for each header */
+#define MD_QUOTE 16 /* 'Quote' $ and space in target name */
+
+static FILE * mkdep_fp; /* For -Mx option */
+static char * mkdep_target;
+ /* For -MT TARGET option and for GCC's queer environment variables. */
+static char * mkdep_mf; /* Argument of -MF option */
+static char * mkdep_md; /* Argument of -MD option */
+static char * mkdep_mq; /* Argument of -MQ option */
+static char * mkdep_mt; /* Argument of -MT option */
+
+/* sharp_filename is filename for #line line, used only in cur_file() */
+static char * sharp_filename = NULL;
+
+static char * argv0; /* argv[ 0] for usage() and version() */
+
+#if COMPILER == GNUC
+/* sys_dirp indicates the first directory to search for system headers */
+static const char ** sys_dirp = incdir; /* For -I- option */
+static int gcc_work_dir = FALSE; /* For -fworking-directory */
+static int put_info_done = FALSE; /* put_info() has been executed */
+static int no_exceptions = FALSE; /* For -fno-deprecated option */
+#endif
+
+#if COMPILER == GNUC || COMPILER == MSC
+/*
+ * preinclude points to the file specified by -include (-Fl for MSC) option,
+ * which is included prior to the main input file.
+ */
+#define NPREINCLUDE 8
+static char * preinclude[ NPREINCLUDE]; /* File to pre-include */
+static char ** preinc_end = preinclude; /* -> active end of preinclude */
+static int dMflag = FALSE; /* Flag of -dM option */
+#endif
+
+#if COMPILER == LCC
+static const char * optim_name = "__LCCOPTIMLEVEL";
+#endif
+
+#if SYSTEM == SYS_CYGWIN
+static int no_cygwin = FALSE; /* -mno-cygwin */
+#endif
+
+#if MCPP_LIB
+void init_system( void)
+/* Initialize static variables */
+{
+ if (sharp_filename)
+ ACE_OS::free( sharp_filename);
+ sharp_filename = 0;
+ incend = incdir;
+ fname_end = fnamelist;
+ start_inc = 0;
+ search_rule = SEARCH_INIT;
+ mb_changed = dDflag = nflag = FALSE;
+ mkdep_fp = 0;
+ mkdep_target = mkdep_mf = mkdep_md = mkdep_mq = mkdep_mt = 0;
+#if COMPILER == GNUC
+ sys_dirp = incdir;
+ gcc_work_dir = put_info_done = no_exceptions = FALSE;
+#endif
+#if COMPILER == GNUC || COMPILER == MSC
+ preinc_end = preinclude;
+ dMflag = FALSE;
+#endif
+#if SYSTEM == SYS_CYGWIN
+ no_cygwin = FALSE;
+#endif
+}
+#endif
+
+#define LINE90LIMIT 32767
+#define LINE_CPLUS_LIMIT 32767
+
+#define OPTLISTLEN 80
+
+void do_options(
+ int argc,
+ char ** argv,
+ char ** in_pp, /* Input file name */
+ char ** out_pp /* Output file name */
+)
+/*
+ * Process command line arguments (-D, etc.), called only at MCPP startup.
+ */
+{
+ char optlist[ OPTLISTLEN]; /* List of option letter*/
+ const char * warning = "warning: -%c%s option is ignored\n";
+ int vflag; /* -v option */
+ int unset_sys_dirs;
+ /* Unset system-specific and site-specific include directories ? */
+ int set_cplus_dir; /* Set C++ include directory ? (for GCC)*/
+ int show_path; /* Show include directory list */
+ DEFBUF * defp;
+ int i;
+ int opt;
+ char * cp;
+
+ long std_val; /* Value of __STDC_VERSION__ or __cplusplus */
+ VAL_SIGN *valp;
+ int sflag; /* -S option or similar */
+ int ansi, trad; /* -ansi, -traditional */
+ int old_mode; /* backup of 'mcpp_mode'*/
+#if COMPILER == GNUC
+#define NSYSDIR 8
+ /* System include directory specified by -isystem */
+ char * sysdir[ NSYSDIR] = { 0, };
+ char ** sysdir_end = sysdir;
+ int integrated_cpp; /* Flag of cc1 which integrates cpp in it */
+ int gcc_maj_ver, gcc_min_ver; /* __GNUC__, __GNUC_MINOR__ */
+#elif COMPILER == MSC
+ int wchar_t_modified = FALSE; /* -Zc:wchar_t flag */
+#elif COMPILER == LCC
+ const char * debug_name = "__LCCDEBUGLEVEL";
+#endif
+
+ argv0 = argv[ 0];
+ vflag = nflag = unset_sys_dirs = show_path = FALSE;
+ set_cplus_dir = TRUE;
+ sflag = ansi = trad = FALSE;
+ std_val = -1L;
+
+ /* Get current directory for -I option and #pragma once */
+ ACE_OS::getcwd( cur_work_dir, FILENAMEMAX);
+#if FNAME_FOLD
+ conv_case( cur_work_dir, cur_work_dir + ACE_OS::strlen( cur_work_dir), LOWER);
+#endif
+#if SYS_FAMILY == SYS_WIN
+ bsl2sl( cur_work_dir);
+#endif
+ ACE_OS::sprintf( cur_work_dir + ACE_OS::strlen( cur_work_dir), "%c%c", PATH_DELIM, EOS);
+ /* Append trailing path-delimiter */
+
+#if COMPILER == GNUC
+ defp = look_id( "__GNUC__");
+ gcc_maj_ver = ACE_OS::atoi( defp->repl);
+ defp = look_id( "__GNUC_MINOR__");
+ gcc_min_ver = ACE_OS::atoi( defp->repl);
+ integrated_cpp = ((gcc_maj_ver == 3 && gcc_min_ver >= 3)
+ || gcc_maj_ver == 4);
+#endif
+
+ set_opt_list( optlist);
+ //FUZZ: disable check_for_lack_ACE_OS
+opt_search: ;
+ while (optind < argc
+ && (opt = getopt( argc, argv, optlist)) != EOF) {
+ //FUZZ: enable check_for_lack_ACE_OS
+ switch (opt) { /* Command line option character */
+
+#if COMPILER == GNUC && ! DOLLAR_IN_NAME
+ case '$': /* Forbid '$' in identifier */
+ break; /* Ignore this option */
+#endif
+
+ case '+':
+#if COMPILER == GNUC
+plus:
+#endif
+ if (cplus_val || sflag) {
+ mcpp_fputs( "warning: -+ option is ignored\n", ERR);
+ break;
+ }
+ cplus_val = CPLUS;
+ break;
+ case '2': /* Revert digraphs recognition */
+ dig_flag = ! dig_flag;
+ break;
+ case '3': /* Revert trigraph recogniion */
+ trig_flag = ! trig_flag;
+ break;
+
+ case '@': /* Special preprocessing mode */
+ old_mode = mcpp_mode;
+ if (str_eq( optarg, "post") || str_eq( optarg, "poststd"))
+ mcpp_mode = POST_STD; /* 'post-Standard' mode */
+ else if (str_eq( optarg, "old") || str_eq( optarg, "oldprep"))
+ mcpp_mode = OLD_PREP; /* 'old-Preprocessor' mode */
+ else if (str_eq( optarg, "kr"))
+ mcpp_mode = KR; /* 'K&R 1st' mode */
+ else if (str_eq( optarg, "std"))
+ mcpp_mode = STD; /* 'Standard' mode (default)*/
+ else if (str_eq( optarg, "compat")) {
+ compat_mode = TRUE; /* 'compatible' mode */
+ mcpp_mode = STD;
+ }
+ else
+ usage( opt);
+ standard = (mcpp_mode == STD || mcpp_mode == POST_STD);
+ if (old_mode != STD && old_mode != mcpp_mode)
+ mcpp_fprintf( ERR, "Mode is redefined to: %s\n", optarg);
+ break;
+
+#if COMPILER == GNUC
+ case 'A': /* Ignore -A system(gnu), -A cpu(vax) or so */
+ break;
+ case 'a':
+ if (str_eq( optarg, "nsi")) { /* -ansi */
+ look_and_install( "__STRICT_ANSI__", DEF_NOARGS, "", "1");
+ ansi = TRUE;
+ break;
+ }
+ usage( opt);
+#elif COMPILER == MSC
+ case 'a':
+ if (ACE_OS::memcmp( optarg, "rch", 3) == 0) {
+ if (str_eq( optarg + 3, ":SSE") /* -arch:SSE */
+ || str_eq( optarg + 3, ":sse"))
+ look_and_install( "_M_IX86_FP", DEF_NOARGS, null, "1");
+ else if (str_eq( optarg + 3, ":SSE2") /* -arch:SSE2 */
+ || str_eq( optarg + 3, ":sse2"))
+ look_and_install( "_M_IX86_FP", DEF_NOARGS, null, "2");
+ /* Else ignore */
+ } else {
+ usage( opt);
+ }
+ break;
+
+ case 'A':
+ lang_asm = TRUE; /* "assembler" source */
+ break;
+#else
+ case 'a':
+ lang_asm = TRUE; /* "assembler" source */
+ break;
+#endif
+
+#if ! STD_LINE_PREFIX
+ case 'b':
+ std_line_prefix = TRUE; /* Putout line and file infor- */
+ break; /* mation in C source style. */
+#endif
+
+ case 'C': /* Keep comments */
+ cflag = TRUE;
+ break;
+
+#if COMPILER == GNUC
+ case 'c':
+ if (! integrated_cpp)
+ usage( opt);
+ break; /* Else ignore this option */
+ case 'd':
+ if (str_eq( optarg, "M")) { /* -dM */
+ dMflag = TRUE;
+ no_output++;
+ } else if (str_eq( optarg, "D")) { /* -dD */
+ dDflag = TRUE;
+ } else if (str_eq( optarg, "igraphs")) { /* -digraphs */
+ dig_flag = TRUE;
+ } else if (str_eq( optarg, "umpbase")) { /* -dumpbase */
+ ; /* Ignore */
+ } else {
+ usage( opt);
+ }
+ break;
+#endif /* COMPILER == GNUC */
+
+ case 'D': /* Define symbol */
+ def_a_macro( opt, optarg);
+ break;
+
+ case 'e':
+ /* Change the default MBCHAR encoding */
+ if (set_encoding( optarg, FALSE, 0) == 0)
+ usage( opt);
+ mb_changed = TRUE;
+ break;
+
+#if COMPILER == GNUC
+ case 'E':
+ if (! integrated_cpp)
+ usage( opt);
+ break; /* Ignore this option */
+ case 'f':
+ if (ACE_OS::memcmp( optarg, "input-charset=", 14) == 0) {
+ /* Treat -finput-charset= as the same option as -e */
+ if (set_encoding( optarg + 14, FALSE, 0) == 0)
+ usage( opt);
+ mb_changed = TRUE;
+ break;
+ } else if (str_eq( optarg, "working-directory")) {
+ gcc_work_dir = TRUE;
+ break;
+ } else if (str_eq( optarg, "no-working-directory")) {
+ gcc_work_dir = FALSE;
+ break;
+ } else if (str_eq( optarg, "stack-protector")) {
+ look_and_install( "__SSP__", DEF_NOARGS, null, "1");
+ break;
+ } else if (str_eq( optarg, "stack-protector-all")) {
+ look_and_install( "__SSP_ALL__", DEF_NOARGS, null, "2");
+ break;
+ } else if (str_eq( optarg, "exceptions")) {
+ look_and_install( "__EXCEPTIONS", DEF_NOARGS, null, "1");
+ break;
+ } else if (str_eq( optarg, "no-exceptions")) {
+ no_exceptions = TRUE;
+ break;
+ } else if (str_eq( optarg, "PIC") || str_eq( optarg, "pic")
+ || str_eq( optarg, "PIE") || str_eq( optarg, "pie")) {
+ look_and_install( "__PIC__", DEF_NOARGS, null, "1");
+ look_and_install( "__pic__", DEF_NOARGS, null, "1");
+ break;
+ } else if (str_eq( optarg, "no-show-column")) {
+ break; /* Ignore this option */
+ } else if (! integrated_cpp) {
+ usage( opt);
+ }
+ break;
+
+ case 'g':
+ if (!ACE_OS::ace_isdigit( *optarg) && str_eq( argv[ optind - 2], "-g"))
+ optind--; /* Neither '-g 0' nor '-ggdb' -- No argument */
+ break; /* Ignore the option */
+#elif COMPILER == LCC
+ case 'g': /* Define __LCCDEBUGLEVEL as <n> */
+ if (*(optarg + 1) == EOS && ACE_OS::ace_isdigit( *optarg)) {
+ defp = look_id( debug_name);
+ ACE_OS::strcpy( defp->repl, optarg);
+ } else {
+ usage( opt);
+ }
+ break;
+#elif COMPILER == MSC
+ case 'G':
+ if (*(optarg + 1) == EOS) { /* -Gx */
+ char val[ 4] = "000";
+
+ switch (*optarg) {
+ case '3': case '4': case '5': case '6':
+ *val = *optarg; /* "300", "400", "500", "600" */
+ break;
+ case 'B': /* -GB */
+ *val = '6';
+ break;
+ case 'R':
+ look_and_install( "_CPPRTTI", DEF_NOARGS, null, "1");
+ break;
+ case 'X':
+ look_and_install( "_CPPUNWIND", DEF_NOARGS, null, "1");
+ break;
+ case 'Z':
+ look_and_install( "__MSVC_RUNTIME_CHECKS", DEF_NOARGS
+ , null, "1");
+ break;
+ default :
+ mcpp_fprintf( ERR, warning, opt, optarg);
+ }
+ if (*val)
+ look_and_install( COMPILER_SP2, DEF_NOARGS, null, val);
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+ case 'h':
+ if (*(optarg + 1) == EOS && ACE_OS::ace_isdigit( *optarg)) /* a digit */
+ look_and_install( "__STDC_HOSTED__", DEF_NOARGS - 1, null
+ , optarg);
+ else
+ usage( opt);
+ break;
+
+#if COMPILER == MSC
+ case 'X':
+ unset_sys_dirs = TRUE;
+ break;
+#endif
+ case 'I': /* Include directory */
+ if (str_eq( optarg, "-")) { /* -I- */
+#if COMPILER == GNUC
+ sys_dirp = incend; /* Split include directories */
+#else
+ unset_sys_dirs = TRUE; /* Unset pre-specified */
+ break; /* include directories*/
+#endif
+ }
+ if (*(optarg + 1) == EOS && ACE_OS::ace_isdigit( *optarg)
+ && (i = *optarg - '0') != 0
+ && (i & ~(CURRENT | SOURCE)) == 0) {
+ search_rule = i; /* -I1, -I2 or -I3 */
+ break;
+ }
+ set_a_dir( optarg); /* User-defined direct. */
+ break;
+
+#if COMPILER == MSC
+ case 'F':
+ if (str_eq( optarg, "l")) { /* -Fl */
+ if (preinc_end >= &preinclude[ NPREINCLUDE]) {
+ mcpp_fputs( "Too many -Fl options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ *preinc_end++ = argv[ optind++];
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+#if COMPILER == GNUC
+ case 'i':
+ if (str_eq( optarg, "nclude")) { /* -include */
+ if (preinc_end >= &preinclude[ NPREINCLUDE]) {
+ mcpp_fputs( "Too many -include options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ *preinc_end++ = argv[ optind++];
+ } else if (str_eq( optarg, "system")) { /* -isystem */
+ if (sysdir_end >= &sysdir[ NSYSDIR]) {
+ mcpp_fputs( "Too many -isystem options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ *sysdir_end++ = argv[ optind++];
+ /* Add the directory before system include directory*/
+ } else if (str_eq( optarg, "prefix") /* -iprefix */
+ || str_eq( optarg, "withprefix") /* -iwithprefix */
+ || str_eq( optarg, "withprefixbefore")
+ /* -iwithprefixbefore */
+ || str_eq( optarg, "dirafter")) { /* -idirafter */
+ optind++; /* Skip the argument */
+ /* Ignore these options */
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+ case 'j':
+ no_source_line = TRUE;
+ break; /* Do not output the source line in diagnostics */
+
+#if COMPILER == MSC
+ case 'J':
+ look_and_install( "_CHAR_UNSIGNED", DEF_NOARGS, null, "1");
+ break;
+#endif
+
+#if COMPILER == GNUC
+ case 'l':
+ if (ACE_OS::memcmp( optarg, "ang-", 4) != 0) {
+ usage( opt);
+ } else if (str_eq( optarg + 4, "c")) { /* -lang-c */
+ break; /* Ignore this option */
+ } else if (str_eq( optarg + 4, "c99") /* -lang-c99*/
+ || str_eq( optarg + 4, "c9x")) { /* -lang-c9x */
+ if (! sflag) {
+ look_and_install( "__STRICT_ANSI__", DEF_NOARGS, "", "1");
+ stdc_val = 1; /* Define __STDC__ to 1 */
+ std_val = 199901L;
+ sflag = TRUE;
+ }
+ } else if (str_eq( optarg + 4, "c89")) { /* -lang-c89*/
+ if (! sflag) {
+ look_and_install( "__STRICT_ANSI__", DEF_NOARGS, "", "1");
+ stdc_val = 1; /* Define __STDC__ to 1 */
+ sflag = TRUE;
+ }
+ } else if (str_eq( optarg + 4, "c++")) { /* -lang-c++*/
+ goto plus;
+ } else if (str_eq( optarg + 4, "asm")) { /* -lang-asm*/
+ lang_asm = TRUE;
+ break;
+ } else {
+ usage( opt);
+ }
+ break;
+#endif /* COMPILER == GNUC */
+
+ case 'M': /* Output source file dependency line */
+ if (str_eq( optarg, "M")) { /* -MM */
+ ;
+ } else if (str_eq( optarg, "D")) { /* -MD */
+ mkdep |= (MD_SYSHEADER | MD_FILE);
+ } else if (str_eq( optarg, "MD")) { /* -MMD */
+ mkdep |= MD_FILE;
+ } else if (str_eq( optarg, "P")) { /* -MP */
+ mkdep |= MD_PHONY;
+ } else if (str_eq( optarg, "Q")) { /* -MQ target */
+ mkdep |= MD_QUOTE;
+ mkdep_mq = argv[ optind++];
+ } else if (str_eq( optarg, "T")) { /* -MT target */
+ mkdep_mt = argv[ optind++];
+ } else if (str_eq( optarg, "F")) { /* -MF file */
+ mkdep_mf = argv[ optind++];
+ } else if (argv[ optind - 1] == optarg) { /* -M */
+ mkdep |= MD_SYSHEADER;
+ optind--;
+ } else {
+ usage( opt);
+ }
+ if (str_eq( optarg, "D") || str_eq( optarg, "MD")) {
+ cp = argv[ optind];
+ if (cp && *cp != '-') /* -MD (-MMD) file */
+ mkdep_md = argv[ optind++];
+ }
+ mkdep |= MD_MKDEP;
+ break;
+
+#if COMPILER == GNUC
+ case 'm':
+#if SYSTEM == SYS_CYGWIN
+ if (str_eq( optarg, "no-cygwin")) { /* -mno-cygwin */
+ no_cygwin = TRUE;
+ break;
+ }
+#endif
+ if (! integrated_cpp)
+ usage( opt);
+ break;
+#endif
+
+#if COMPILER == GNUC
+ case 'u':
+ if (! str_eq( optarg, "ndef")) /* -undef */
+ usage( opt); /* Else fall through */
+#endif
+
+#if COMPILER == MSC
+ case 'u':
+#endif
+ case 'N':
+ /* No predefines: remove "vax", "__VAX" and friends. */
+ nflag = TRUE;
+ break;
+
+#if COMPILER == GNUC
+ case 'n':
+ if (str_eq( optarg, "ostdinc")) { /* -nostdinc */
+ unset_sys_dirs = TRUE; /* Unset pre-specified directories */
+ } else if (str_eq( optarg, "ostdinc++")) { /* -nostdinc++ */
+ set_cplus_dir = FALSE; /* Unset C++-specific directories */
+ } else if (str_eq( optarg, "oprecomp")) { /* -noprecomp */
+ mcpp_fprintf( ERR, warning, opt, optarg);
+ break;
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+#if COMPILER == GNUC
+ case 'O':
+ if (integrated_cpp) {
+ if (*optarg == '-') /* No argument */
+ optind--;
+ else if (! ACE_OS::ace_isdigit( *optarg))
+ usage( opt);
+ else if (*optarg != '0')
+ look_and_install( "__OPTIMIZE__", DEF_NOARGS, "", "1");
+ } else {
+ usage( opt);
+ }
+ break; /* Else ignore -Ox option */
+#elif COMPILER == LCC
+ case 'O': /* Define __LCCOPTIMLEVEL as 1 */
+ defp = look_id( optim_name);
+ ACE_OS::strcpy( defp->repl, "1");
+ break;
+#endif
+
+ case 'o':
+ *out_pp = optarg; /* Output file name */
+ break;
+
+ case 'P': /* No #line output */
+ pflag = TRUE;
+ break;
+
+#if COMPILER == GNUC
+ case 'p':
+ if (str_eq( optarg, "edantic") /* -pedantic */
+ || str_eq( optarg, "edantic-errors")) {
+ /* -pedantic-errors */
+ if (warn_level == -1)
+ warn_level = 0;
+ warn_level |= (1 | 2 | 4);
+ if (! sflag && ! cplus_val) {
+ stdc_val = 1;
+ sflag = TRUE;
+ }
+ } else {
+ usage( opt);
+ }
+ break;
+ case 'q':
+ if (str_eq( optarg, "uiet")) /* -quiet */
+ break; /* Ignore the option */
+ else
+ usage( opt);
+ break;
+#endif /* COMPILER == GNUC */
+
+ case 'Q':
+ qflag = TRUE;
+ break;
+
+#if COMPILER == MSC
+ case 'R': /* -RTC1, -RTCc, -RTCs, -RTCu, etc. */
+ if (ACE_OS::memcmp( optarg, "TC", 2) == 0 && *(optarg + 2) != EOS)
+ look_and_install( "__MSVC_RUNTIME_CHECKS", DEF_NOARGS, null
+ , "1");
+ else
+ usage( opt);
+ break;
+#endif
+
+ case 'S':
+ if (cplus_val || sflag) { /* C++ or the second time */
+ mcpp_fprintf( ERR, warning, opt, optarg);
+ break;
+ }
+ i = *optarg;
+ if (! ACE_OS::ace_isdigit( i) || *(optarg + 1) != EOS)
+ usage( opt);
+ stdc_val = i - '0';
+ sflag = TRUE;
+ break;
+
+#if COMPILER == GNUC
+ case 'r':
+ if (str_eq( optarg, "emap"))
+ mcpp_fprintf( ERR, warning, opt, optarg);
+ /* Ignore -remap option */
+ else
+ usage( opt);
+ break;
+
+ case 's':
+ if (ACE_OS::memcmp( optarg, "td=", 3) == 0 && ACE_OS::strlen( optarg) > 3) {
+ /* -std=STANDARD */
+ cp = optarg + 3;
+ if (str_eq( cp, "c89") /* std=c89 */
+ || str_eq( cp, "c90") /* std=c90 */
+ || str_eq( cp, "gnu89") /* std=gnu89 */
+ || str_eq( cp, "iso9899:1990")) {
+ std_val = 0L; /* C90 + extensions */
+ } else if (str_eq( cp, "c99") /* std=c99 */
+ || str_eq( cp, "c9x") /* std=c9x */
+ || str_eq( cp, "gnu99") /* std=gnu99 */
+ || str_eq( cp, "gnu9x") /* std=gnu9x */
+ || str_eq( cp, "iso9899:1999")
+ || str_eq( cp, "iso9899:199x")) {
+ std_val = 199901L;
+ } else if (str_eq( cp, "c++98")) { /* std=c++98 */
+ cplus_val = std_val = 199711L;
+ } else if (ACE_OS::memcmp( cp, "iso9899:", 8) == 0
+ && ACE_OS::strlen( cp) >= 14) { /* std=iso9899:199409, etc. */
+ optarg = cp + 8;
+ goto Version;
+ } else if (ACE_OS::memcmp( cp, "iso14882", 8) == 0) {
+ cp += 8;
+ if (cp && *cp == ':' && ACE_OS::strlen( cp) >= 7) {
+ /* std=iso14882:199711, etc. */
+ cplus_val = CPLUS;
+ optarg = cp + 1;
+ goto Version;
+ } else {
+ goto plus;
+ }
+ } else {
+ usage( opt);
+ }
+ if (! cplus_val && ACE_OS::memcmp( cp, "gnu", 3) != 0)
+ look_and_install( "__STRICT_ANSI__", DEF_NOARGS, "", "1");
+ stdc_val = 1;
+ sflag = TRUE;
+ } else {
+ usage( opt);
+ }
+ break;
+
+ case 't':
+ if (str_eq( optarg, "raditional")
+ || str_eq( optarg, "raditional-cpp")) {
+ /* -traditional, -traditional-cpp */
+ trad = TRUE;
+ mcpp_mode = OLD_PREP;
+ } else if (str_eq( optarg, "rigraphs")) {
+ trig_flag = TRUE; /* -trigraphs */
+ } else {
+ usage( opt);
+ }
+ break;
+#endif /* COMPILER == GNUC */
+
+#if COMPILER == MSC
+ case 'T':
+ if (ACE_OS::strlen( optarg) > 1)
+ usage( opt);
+ i = ACE_OS::tolower( *optarg); /* Fold case */
+ if (i == 'c') {
+ break; /* Ignore this option */
+ } else if (i == 'p') {
+ cplus_val = CPLUS;
+ break;
+ } else {
+ usage( opt);
+ }
+#endif
+
+ case 'U': /* Undefine symbol */
+ /*
+ * We don't need to map trigraphs as they can't be part of a
+ * symbol name. (_ isn't trigraphable).
+ */
+ if ((defp = look_id( optarg)) != 0) {
+ if (defp->nargs == DEF_NOARGS - 1) {
+ undef_a_predef( optarg);
+ }
+ undefine( optarg);
+ } else {
+ mcpp_fprintf( ERR, "\"%s\" wasn't defined\n", optarg);
+ }
+ break;
+
+ case 'V':
+#if COMPILER == GNUC
+Version:
+#endif
+ valp = eval_num( optarg);
+ if (valp->sign == VAL_ERROR)
+ usage( opt);
+ std_val = (long) valp->val;
+ break;
+
+ case 'v':
+ vflag = TRUE;
+ show_path = TRUE;
+ break;
+
+ case 'W': /* warning level */
+ if (warn_level == -1) /* Have to initialize */
+ warn_level = 0;
+#if COMPILER == GNUC
+ if (argv[ optind - 1] == optarg) { /* No argument */
+ /*
+ * Note: -W without argument is not officially supported.
+ * It may cause an error.
+ */
+ warn_level |= (1 | 2 | 4 | 16);
+ optind--;
+ break;
+ } else if (str_eq( optarg, "comment")
+ || str_eq( optarg, "comments")
+ || str_eq( optarg, "sign-compare")) {
+ warn_level |= 1;
+ break;
+ } else if (str_eq( optarg, "undef")) {
+ warn_level |= 4;
+ break;
+ } else if (str_eq( optarg, "all")) {
+ warn_level |= (1 | 16); /* Convert -Wall to -W17*/
+ break;
+ } else if (str_eq( optarg, "trigraphs")) {
+ warn_level |= 16;
+ break;
+ }
+#endif /* COMPILER == GNUC */
+#if COMPILER == MSC
+ if (str_eq( optarg, "all")) {
+ warn_level |= (1 | 16); /* Convert -Wall to -W17*/
+ break;
+ } else if (str_eq( optarg, "L")) {
+ no_source_line = TRUE; /* Single-line diagnostic */
+ break;
+ }
+#endif
+ if (ACE_OS::ace_isdigit( *optarg)) {
+ warn_level |= parse_warn_level( optarg, opt);
+ if (warn_level > 31 || warn_level < 0)
+ usage( opt);
+ }
+ if (warn_level == 0)
+ warn_level = 0xFF; /* Remember this option */
+ /* Else ignore the option */
+ break;
+
+#if COMPILER == GNUC || COMPILER == MSC
+ case 'w': /* Same as -W0 */
+ warn_level = 0xFF; /* Remenber this option */
+ break;
+#endif
+
+#if COMPILER == GNUC
+ case 'x':
+ if (str_eq( optarg, "c")) {
+ break; /* -x c -- ignore this */
+ } else if (str_eq( optarg, "c++")) {
+ goto plus;
+ } else if (str_eq( optarg, "assembler-with-cpp")) {
+ lang_asm = TRUE;
+ break;
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+#if COMPILER == MSC
+ case 'Z':
+ if (str_eq( optarg, "c:wchar_t")) { /* -Zc:wchar_t */
+ look_and_install( "_NATIVE_WCHAR_T_DEFINED", DEF_NOARGS, null
+ , "1");
+ look_and_install( "_WCHAR_T_DEFINED", DEF_NOARGS, null, "1");
+ wchar_t_modified = TRUE;
+ } else if (str_eq( optarg, "c:wchar_t-")) { /* -Zc:wchar_t- */
+ wchar_t_modified = TRUE; /* Do not define the macros */
+ } else if (str_eq( optarg, "l")) {
+ look_and_install( "_VC_NODEFAULTLIB", DEF_NOARGS, null, "1");
+ } else if (str_eq( optarg, "a") || str_eq( optarg, "e")) {
+ /* Ignore -Za and -Ze silently */
+ break;
+ } else if (*(optarg + 1) == EOS) { /* -Z followed by one char */
+ mcpp_fprintf( ERR, warning, opt, optarg);
+ /* Ignore the option with warning */
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+ case 'z':
+ zflag = TRUE; /* No output of included file */
+ break;
+
+ default: /* What is this one? */
+ usage( opt);
+ break;
+ } /* Switch on all options */
+
+ } /* For all arguments */
+
+ if (optind < argc && set_files( argc, argv, in_pp, out_pp) != 0)
+ goto opt_search; /* More options after the filename */
+
+ /* Check consistency of specified options, set some variables */
+ chk_opts( sflag, std_val, ansi, trad);
+
+ if (warn_level == -1) /* No -W option */
+ warn_level = 1; /* Default warning level */
+ else if (warn_level == 0xFF)
+ warn_level = 0; /* -W0 has high precedence */
+
+#if COMPILER == GNUC
+ if (sysdir < sysdir_end) {
+ char ** dp = sysdir;
+ while (dp < sysdir_end)
+ set_a_dir( *dp++);
+ }
+ if (*in_pp && str_eq( (*in_pp) + ACE_OS::strlen( *in_pp) - 2, ".S"))
+ lang_asm = TRUE; /* Input file name is *.S */
+ if (lang_asm)
+ look_and_install( "__ASSEMBLER__", DEF_NOARGS, null, "1");
+#endif
+ set_env_dirs();
+ if (! unset_sys_dirs)
+ set_sys_dirs( set_cplus_dir);
+
+ if (mkdep_mf) { /* -MF overrides -MD */
+ mkdep_fp = ACE_OS::fopen( mkdep_mf, "w");
+ } else if (mkdep_md) {
+ mkdep_fp = ACE_OS::fopen( mkdep_md, "w");
+ }
+ if (mkdep_mq) /* -MQ overrides -MT */
+ mkdep_target = mkdep_mq;
+ else if (mkdep_mt)
+ mkdep_target = mkdep_mt;
+
+#if COMPILER == GNUC
+ init_gcc_macro( gcc_maj_ver, gcc_min_ver);
+ chk_env(); /* Check the env-vars to specify version and dependency line*/
+#elif COMPILER == MSC
+ init_msc_macro( wchar_t_modified);
+#endif
+
+ init_predefines( nflag, std_val);
+
+ if (vflag)
+ version();
+ if (show_path) {
+ fp_debug = stderr;
+ dump_path();
+ fp_debug = stdout;
+ }
+}
+
+static void version( void)
+/*
+ * Print version message.
+ */
+{
+ const char * mes[] = {
+
+#if MCPP_LIB
+/* Write messages here. */
+ 0, " with ",
+#endif
+
+#ifdef VERSION_MSG
+ "MCPP V.2.6.4 (2007/05) "
+#else
+ "MCPP V.", VERSION, " (", DATE, ") "
+#endif
+#if COMPILER == INDEPENDENT
+ , "compiler-independent-build "
+#else
+#ifdef CMP_NAME
+ , "for ", CMP_NAME, " "
+#endif
+#endif
+ , "compiled by "
+#ifdef VERSION_MSG
+ , VERSION_MSG
+#else
+#ifdef HOST_CMP_NAME
+ , HOST_CMP_NAME
+#if HOST_COMPILER == GNUC
+ , " V.", GCC_MAJOR_VERSION, ".", GCC_MINOR_VERSION
+#endif
+#endif
+#endif
+ , "\n",
+ 0
+ };
+
+ const char ** mpp = mes;
+#if MCPP_LIB
+ mes[ 0] = argv0;
+#endif
+ while (*mpp)
+ mcpp_fputs( *mpp++, ERR);
+}
+
+static void usage(
+ int opt
+)
+/*
+ * Print usage.
+ */
+{
+ const char * mes[] = {
+
+"Usage: ",
+"mcpp",
+" [-<opts> [-<opts>]] [<infile> [-<opts>] [<outfile>] [-<opts>]]\n",
+" <infile> defaults to stdin and <outfile> defaults to stdout.\n",
+
+"\nCommonly used options:\n",
+
+"-@MODE Specify preprocessing mode. MODE should be one of these 4:\n",
+" -@std Standard conforming mode. (default)\n",
+" -@poststd, -@post special 'post-Standard' mode.\n",
+" -@kr K&R 1st mode.\n",
+" -@oldprep, -@old 'old_preprocessor' mode (i.e. 'Reiser model' cpp).\n",
+
+#if COMPILER == MSC
+"-arch:SSE, -arch:SSE2 Define the macro _M_IX86_FP as 1, 2 respectively.\n",
+#endif
+
+#if ! STD_LINE_PREFIX
+"-b Output #line lines in C source style.\n",
+#endif
+
+"-C Output also comments.\n",
+"-D <macro>[=<value>] Define <macro> as <value> (default:1).\n",
+"-D <macro(args)>[=<replace>] Define <macro(args)> as <replace>.\n",
+"-e <encoding> Change the default multi-byte character encoding to one of:\n",
+" euc_jp, gb2312, ksc5601, big5, sjis, iso2022_jp, utf8.\n",
+
+#if COMPILER == GNUC
+"-finput-charset=<encoding> Same as -e <encoding>.\n",
+" (Don't insert spaces around '=').\n",
+#endif
+#if COMPILER == MSC
+"-Fl <file> Include the <file> prior to the main input file.\n",
+"-G<n> Define the macro _M_IX86 according to <n>.\n",
+#endif
+#if COMPILER == LCC
+"-g <n> Define the macro __LCCDEBUGLEVEL as <n>.\n",
+#endif
+
+"-I <directory> Add <directory> to the #include search list.\n",
+"-I- Unset system or site specific include directories.\n",
+
+#if COMPILER == GNUC
+"-include <file> Include the <file> prior to the main input file.\n",
+#endif
+#if COMPILER == MSC
+"-J Define the macro _CHAR_UNSIGNED as 1.\n",
+#endif
+
+"-j Don't output the source line in diagnostics.\n",
+"-M, -MM, -MD, -MMD, -MP, -MQ target, -MT target, -MF file\n",
+" Output source file dependency line for makefile.\n",
+"-N Don't predefine any non-standard macros.\n",
+
+#if COMPILER == GNUC
+"-nostdinc Unset system or site specific include directories.\n",
+#endif
+#if COMPILER == LCC
+"-O Define the macro __LCCOPTIMLEVEL as 1.\n",
+#endif
+
+"-o <file> Output to <file>.\n",
+"-P Don't output #line lines.\n",
+"-Q Output diagnostics to \"mcpp.err\" (default:stderr).\n",
+#if COMPILER == MSC
+"-RTC* Define the macro __MSVC_RUNTIME_CHECKS as 1.\n",
+#endif
+#if COMPILER == GNUC
+"-traditional, -traditional-cpp Same as -@oldprep.\n",
+#endif
+"-U <macro> Undefine <macro>.\n",
+
+#if COMPILER == GNUC
+"-undef Same as -N.\n",
+#endif
+#if COMPILER == MSC
+"-u Same as -N.\n",
+#endif
+
+"-v Show version and include directories of mcpp.\n",
+"-W <level> Set warning level to <level> (OR of {0,1,2,4,8,16}, default:1).\n",
+
+#if COMPILER == MSC
+"-WL Same as -j.\n",
+#endif
+#if COMPILER == MSC || COMPILER == GNUC
+"-w Same as -W0.\n",
+#endif
+#if COMPILER == MSC
+"-X Same as -I-.\n",
+"-Zc:wchar_t Define _NATIVE_WCHAR_T_DEFINED and _WCHAR_T_DEFINED as 1.\n",
+"-Zl Define the macro _VC_NODEFAULTLIB as 1.\n",
+#endif
+
+"-z Don't output the included file, only defining macros.\n",
+
+"\nOptions available with -@std (default) or -@poststd options:\n",
+
+"-+ Process C++ source.\n",
+
+#if DIGRAPHS_INIT
+"-2 Disable digraphs.\n",
+#else
+"-2 Enable digraphs.\n",
+#endif
+#if COMPILER == GNUC
+"-digraphs Enable digraphs.\n",
+#endif
+
+"-h <n> Re-define the pre-defined macro __STDC_HOSTED__ as <n>.\n",
+
+#if COMPILER == GNUC
+"-lang-c89 Same as -S1.\n",
+"-lang-c++ Same as -+.\n",
+"-pedantic, -pedantic-errors Same as -W7.\n",
+#endif
+
+"-S <n> Redefine __STDC__ to <n>, undefine old style macros.\n",
+
+#if COMPILER == GNUC
+"-std=<STANDARD> Specify the standard to which the code should conform.\n",
+" <STANDARD> may be one of: c90, c99, iso9899:1990, iso14882, etc.\n",
+" iso9899:<n>, iso14882:<n> : Same as -V <n> (long in decimals).\n",
+#endif
+#if COMPILER == MSC
+"-Tp Same as -+.\n",
+#endif
+
+"-V <n> Redefine __STDC_VERSION__ or __cplusplus to <n>.\n",
+" C with -V199901L specifies C99 specs.\n",
+" C++ with -V199901L specifies C99 compatible specs.\n",
+
+#if COMPILER == GNUC
+"-x c++ Same as -+.\n",
+#endif
+
+"\nOptions available with only -@std (default) option:\n",
+
+"-@compat Expand recursive macro more than Standard.\n",
+#if TRIGRAPHS_INIT
+"-3 Disable trigraphs.\n",
+#else
+"-3 Enable trigraphs.\n",
+#endif
+#if COMPILER == GNUC
+"-trigraphs Enable trigraphs.\n",
+#endif
+
+"\nOptions available with -@std (default), -@kr or -@oldprep options:\n",
+
+#if COMPILER == GNUC
+"-lang-asm Same as -x assembler-with-cpp.\n",
+"-x assembler-with-cpp Process \"assembler\" source.\n",
+#elif COMPILER == MSC
+"-A Process \"assembler\" source.\n",
+#else
+"-a Process \"assembler\" source.\n",
+#endif
+
+"\nFor further details see mcpp-manual.html.\n",
+ 0,
+ };
+
+ const char * illegopt = "Incorrect option -%c%s\n";
+ const char * const * mpp = mes;
+
+ if (opt != '?')
+ mcpp_fprintf( ERR, illegopt, opt, optarg ? optarg : "");
+ version();
+#if MCPP_LIB
+ mes[ 1] = argv0;
+#endif
+ while (*mpp)
+ mcpp_fputs( *mpp++, ERR);
+ longjmp( error_exit, -1);
+}
+
+static void set_opt_list(
+ char * optlist
+)
+/*
+ * Set list of legal option characters.
+ */
+{
+ const char * list[] = {
+
+#if ! STD_LINE_PREFIX
+ "b",
+#endif
+
+#if COMPILER == GNUC
+ "$A:a:cd:Ef:g:i:l:m:n:r:s:t:u:O:p:q:wx:",
+#elif COMPILER != MSC
+ "a",
+#endif
+
+#if COMPILER == MSC
+ "Aa:F:G:JR:T:XZ:uw",
+#elif COMPILER == LCC
+ "g:O",
+#endif
+ 0
+ };
+
+ const char * const * lp = & list[ 0];
+
+ ACE_OS::strcpy( optlist, "23+@:e:h:jo:vzCD:I:M:NPQS:U:V:W:");
+ /* Default options */
+ while (*lp)
+ ACE_OS::strcat( optlist, *lp++);
+ if (ACE_OS::strlen( optlist) >= OPTLISTLEN)
+ cfatal( "Bug: Too long option list", 0, 0L, 0); /* _F_ */
+}
+
+static int parse_warn_level(
+ const char * optarg,
+ int opt
+)
+/*
+ * Parse warn level option.
+ * Warning level option is specified as '19' or '1|2|16' or even '3|16'.
+ * Even spaces are allowed as ' 1 | 2|16 '.
+ */
+{
+ const char * cp = optarg;
+ int w, i;
+
+ w = i = 0;
+ while( *cp != EOS) {
+ while( *cp == ' ')
+ cp++; /* Skip spaces */
+ if (! ACE_OS::ace_isdigit( *cp))
+ break; /* Error */
+ while (ACE_OS::ace_isdigit( *cp)) {
+ i *= 10;
+ i += (*cp++ - '0');
+ }
+ while (*cp == ' ')
+ cp++;
+ if (*cp == '|') { /* Only digits or '|' are allowed */
+ w |= i; /* Take OR of the args */
+ i = 0;
+ cp++;
+ }
+ }
+ if (*cp != EOS) { /* Not ending with digit */
+ mcpp_fprintf( ERR, "Illegal warning level option \"%s\"\n", optarg);
+ usage( opt);
+ }
+ w |= i; /* Take the last arg */
+ return w;
+}
+
+static void def_a_macro(
+ int opt,
+ char * def
+)
+/*
+ * Define a macro specified by -D option.
+ * The macro maybe either object-like or function-like (with parameter).
+ */
+{
+ DEFBUF * defp;
+ char * definition; /* Argument of -D option*/
+ char * cp;
+ int i;
+
+ /* Convert trigraphs for the environment which need trigraphs */
+ if (mcpp_mode == STD && trig_flag)
+ cnv_trigraph( def);
+ if (mcpp_mode == POST_STD && dig_flag)
+ cnv_digraph( def); /* Convert prior to installing macro */
+ definition = xmalloc( ACE_OS::strlen( def) + 4);
+ ACE_OS::strcpy( definition, def);
+ if ((cp = ACE_OS::strchr( definition, '=')) != 0) {
+ *cp = ' '; /* Remove the '=' */
+ cp = "\n"; /* Append <newline> */
+ } else {
+ cp = " 1\n"; /* With definition "1" */
+ }
+ ACE_OS::strcat( definition, cp);
+ cp = definition;
+ while ((char_type[ *cp & UCHARMAX] & SPA) == 0)
+ cp++;
+ i = *cp;
+ *cp = EOS;
+ if ((defp = look_id( definition)) != 0) { /* Pre-defined */
+ if (defp->nargs == DEF_NOARGS - 1) {
+ undef_a_predef( definition);
+ /* Remove the name from the table of pre-defined-macros.*/
+ }
+ undefine( definition);
+ }
+ *cp = i;
+ /* Now, save the definition. */
+ unget_string( definition, 0);
+ if (do_define( FALSE) == 0) /* Define a macro */
+ usage( opt);
+ *cp = EOS;
+ if (str_eq( definition, "__STDC__")) {
+ defp = look_id( definition);
+ defp->nargs = DEF_NOARGS - 2;
+ /* Restore Standard-predefinedness */
+ }
+ ACE_OS::free( definition);
+ skip_nl(); /* Clear the appended <newline> */
+}
+
+static void chk_opts(
+ int sflag, /* Flag of Standard or post-Standard mode */
+ long std_val, /* Value of __STDC_VERSION__ */
+ int ansi, /* -ansi (GCC only) */
+ int trad /* -traditional (GCC only) */
+)
+/*
+ * Check consistency between the specified options.
+ * Set default value of some variables for each 'mcpp_mode'.
+ */
+{
+ int incompat = FALSE;
+
+ switch (mcpp_mode) {
+ case STD :
+ case POST_STD :
+ if (trad)
+ incompat = TRUE;
+ if (! stdc_val)
+ stdc_val = STDC;
+ break;
+ case KR :
+ case OLD_PREP :
+ if (sflag || cplus_val || ansi || std_val != -1L)
+ incompat = TRUE;
+ if (dig_flag) {
+ if (dig_flag != DIGRAPHS_INIT)
+ incompat = TRUE;
+ else
+ dig_flag = 0;
+ }
+ break;
+ }
+ if (mcpp_mode == POST_STD && (lang_asm || compat_mode))
+ incompat = TRUE;
+ if (mcpp_mode != STD && trig_flag) {
+ if (trig_flag != TRIGRAPHS_INIT)
+ incompat = TRUE;
+ else
+ trig_flag = FALSE;
+ }
+ if (incompat) {
+ mcpp_fputs( "Incompatible options are specified.\n", ERR);
+ usage( '?');
+ }
+
+ standard = (mcpp_mode == STD || mcpp_mode == POST_STD);
+ /* Modify magic characters in character type table. */
+ if (! standard)
+ char_type[ DEF_MAGIC] = 0;
+ if (mcpp_mode != STD)
+ char_type[ IN_SRC] = 0;
+ if (mcpp_mode == POST_STD || mcpp_mode == KR)
+ char_type[ TOK_SEP] = 0; /* TOK_SEP equals to COM_SEP */
+
+ expand_init();
+ /* Set function pointer to macro expansion routine */
+}
+
+static void init_predefines(
+ int nflag, /* -N option */
+ long std_val /* Value of __STDC_VERSION__ */
+)
+/*
+ * Set or unset predefined macros.
+ * This routine should be called after init_gcc_macro().
+ */
+{
+ char tmp[ 16];
+
+ if (std_val != -1L) { /* Version is specified */
+ if (cplus_val)
+ cplus_val = std_val; /* Value of __cplusplus */
+ else
+ stdc_ver = std_val; /* Value of __STDC_VERSION__ */
+ } else {
+ if (! cplus_val)
+ stdc_ver = stdc_val ? STDC_VERSION : 0L;
+ }
+
+ if (nflag) {
+ un_predefine( TRUE);
+#if COMPILER == GNUC
+ undef_gcc_macro( TRUE);
+#endif
+ } else if (stdc_val || cplus_val) {
+ un_predefine( FALSE); /* Undefine "unix" or so */
+#if COMPILER == GNUC
+ undef_gcc_macro( FALSE);
+#endif
+ }
+ ACE_OS::sprintf( tmp, "%ldL", cplus_val ? cplus_val : stdc_ver);
+ if (cplus_val) {
+ look_and_install( "__cplusplus", DEF_NOARGS - 2, null, tmp);
+ } else {
+ if (stdc_ver)
+ look_and_install( "__STDC_VERSION__", DEF_NOARGS - 2, null, tmp);
+#ifdef COMPILER_CPLUS
+ if (! nflag) /* Undefine pre-defined macro for C++ */
+ undefine( COMPILER_CPLUS);
+#endif
+ }
+ set_limit();
+ stdc2 = cplus_val || stdc_ver >= 199901L;
+ stdc3 = (cplus_val >= 199901L) || (stdc_ver >= 199901L);
+ /* (cplus_val >= 199901L) makes C++ C99-compatible specs */
+ if (standard)
+ init_std_defines();
+ if (stdc3)
+ set_pragma_op();
+}
+
+static void init_std_defines( void)
+/*
+ * For STD and POST_STD modes.
+ * The magic pre-defines (Standard predefined macros) are initialized with
+ * negative argument counts. expand_macro() notices this and calls the
+ * appropriate routine. DEF_NOARGS is one greater than the first "magic"
+ * definition. 'DEF_NOARGS - n' is reserved for pre-defined macros.
+ * __STDC_VERSION__ and __cplusplus are defined by chk_opts() and set_cplus().
+ */
+{
+ char tmp[ 16];
+ char timestr[ 14];
+ time_t tvec;
+ char * tstring;
+
+ look_and_install( "__LINE__", DEF_NOARGS - 3, null, "-1234567890");
+ /* Room for 11 chars (10 for long and 1 for '-' in case of wrap round. */
+ look_and_install( "__FILE__", DEF_NOARGS - 4, null, null);
+ /* Should be stuffed */
+
+ /* Define __DATE__, __TIME__ as present date and time. */
+ ACE_OS::time( &tvec);
+ tstring = ACE_OS::ctime( &tvec);
+ ACE_OS::sprintf( timestr, "\"%.3s %c%c %.4s\"",
+ tstring + 4,
+ *(tstring + 8) == '0' ? ' ' : *(tstring + 8),
+ *(tstring + 9),
+ tstring + 20);
+ look_and_install( "__DATE__", DEF_NOARGS - 2, null, timestr);
+ ACE_OS::sprintf( timestr, "\"%.8s\"", tstring + 11);
+ look_and_install( "__TIME__", DEF_NOARGS - 2, null, timestr);
+
+ if (! look_id( "__STDC_HOSTED__")) {
+ /*
+ * Some compilers, e.g. GCC older than 3.3, define this macro by
+ * -D option.
+ */
+ ACE_OS::sprintf( tmp, "%d", STDC_HOSTED);
+ look_and_install( "__STDC_HOSTED__", DEF_NOARGS - 1, null, tmp);
+ }
+#if COMPILER != GNUC /* GCC do not undefine __STDC__ on C++ */
+ if (cplus_val)
+ return;
+#endif
+ /* Define __STDC__ as 1 or such for Standard conforming compiler. */
+ if (! look_id( "__STDC__")) {
+ ACE_OS::sprintf( tmp, "%d", stdc_val);
+ look_and_install( "__STDC__", DEF_NOARGS - 2, null, tmp);
+ }
+}
+
+static void set_limit( void)
+/*
+ * Set the minimum translation limits specified by the Standards.
+ */
+{
+ if (cplus_val) { /* Specified by C++ 1998 Standard */
+ str_len_min = SLEN_CPLUS_MIN;
+ id_len_min = IDLEN_CPLUS_MIN;
+ n_mac_pars_min = NMACPARS_CPLUS_MIN;
+ exp_nest_min = EXP_NEST_CPLUS_MIN;
+ blk_nest_min = BLK_NEST_CPLUS_MIN;
+ inc_nest_min = INCLUDE_NEST_CPLUS_MIN;
+ n_macro_min = NMACRO_CPLUS_MIN;
+ line_limit = LINE_CPLUS_LIMIT;
+ } else if (stdc_ver >= 199901L) { /* Specified by C 1999 Standard */
+ str_len_min = SLEN99MIN;
+ id_len_min = IDLEN99MIN;
+ n_mac_pars_min = NMACPARS99MIN;
+ exp_nest_min = EXP_NEST99MIN;
+ blk_nest_min = BLK_NEST99MIN;
+ inc_nest_min = INCLUDE_NEST99MIN;
+ n_macro_min = NMACRO99MIN;
+ line_limit = LINE99LIMIT;
+ } else if (standard) { /* Specified by C 1990 Standard */
+ str_len_min = SLEN90MIN;
+ id_len_min = IDLEN90MIN;
+ n_mac_pars_min = NMACPARS90MIN;
+ exp_nest_min = EXP_NEST90MIN;
+ blk_nest_min = BLK_NEST90MIN;
+ inc_nest_min = INCLUDE_NEST90MIN;
+ n_macro_min = NMACRO90MIN;
+ line_limit = LINE90LIMIT;
+ }
+ /* Else pre-Standard mode */
+}
+
+static void set_pragma_op( void)
+/*
+ * #define _Pragma(a) _Pragma ( a )
+ * Define _Pragma() operator as a special macro so as to be searched
+ * easily. The unusual 'DEF_PRAGMA' is a marker of this psuedo
+ * macro.
+ */
+{
+ char * name = "_Pragma";
+ char tmp[ 16];
+
+ ACE_OS::sprintf( tmp, "%c%s ( %c%c )", DEF_MAGIC, name, MAC_PARM, 1);
+ /* Replacement text */
+ look_and_install( name, DEF_PRAGMA, "a", tmp);
+}
+
+void at_start( void)
+/*
+ * Do the commands prior to processing main source file.
+ */
+{
+ /*
+ * Set multi-byte character encoding according to environment variables
+ * LC_ALL, LC_CTYPE and LANG -- with preference in this order.
+ */
+ char * env;
+
+ if (mb_changed)
+ return; /* -m option precedes */
+ if ((env = ACE_OS::getenv( "LC_ALL")) != 0)
+ set_encoding( env, "LC_ALL", 0);
+ else if ((env = ACE_OS::getenv( "LC_CTYPE")) != 0)
+ set_encoding( env, "LC_CTYPE", 0);
+ else if ((env = ACE_OS::getenv( "LANG")) != 0)
+ set_encoding( env, "LANG", 0);
+
+#if COMPILER == GNUC || COMPILER == MSC
+#if COMPILER == GNUC
+ /* -fworking-directory */
+ if (gcc_work_dir && (preinclude <= --preinc_end && *preinc_end != 0)) {
+ open_include( *preinc_end, TRUE, FALSE);
+ src_line++;
+ put_info(); /* Putout the current directory */
+ src_line--;
+ }
+#endif
+ /*
+ * Do the -include (-Fl for MSC) options in the specified order.
+ * Note: This functionality is implemented as nested #includes
+ * which results the same effect as sequential #includes.
+ */
+ while (preinclude <= --preinc_end && *preinc_end != 0)
+ open_include( *preinc_end, TRUE, FALSE);
+#endif
+}
+
+static char * set_files(
+ int argc,
+ char ** argv,
+ char ** in_pp,
+ char ** out_pp
+)
+/*
+ * Set input and/or output files.
+ */
+{
+ char * cp;
+
+ if (*in_pp == 0) { /* Input file */
+ cp = argv[ optind++];
+#if SYS_FAMILY == SYS_WIN
+ cp = bsl2sl( cp);
+#endif
+ *in_pp = cp;
+ }
+ if (optind < argc && argv[ optind][ 0] != '-' && *out_pp == 0) {
+ cp = argv[ optind++];
+#if SYS_FAMILY == SYS_WIN
+ cp = bsl2sl( cp);
+#endif
+ *out_pp = cp; /* Output file */
+ }
+ if (optind >= argc)
+ return 0; /* Exhausted command line arguments */
+ if (argv[ optind][ 0] == '-')
+ return argv[ optind]; /* More options */
+ cfatal( "Excessive file argument \"%s\"", argv[ optind], 0L , 0);
+ return 0;
+}
+
+static void set_env_dirs( void)
+/*
+ * Add to include path those specified by environment variables.
+ */
+{
+ const char * env;
+
+ if (cplus_val) {
+ if ((env = ACE_OS::getenv( ENV_CPLUS_INCLUDE_DIR)) != 0)
+ parse_env( env);
+ }
+ if ((env = ACE_OS::getenv( ENV_C_INCLUDE_DIR)) != 0)
+ parse_env( env);
+}
+
+static void parse_env(
+ const char * env
+)
+/*
+ * Parse environmental variable and append the path to include-dir-list.
+ */
+{
+ char * save;
+ char * save_start;
+ char * p;
+ int sep;
+
+ save = save_start = save_string( env);
+ while (*save) {
+ p = save;
+ while (*p && *p != ENV_SEP)
+ p++;
+ if (p != save) { /* Variable separator */
+ sep = *p;
+ *p = EOS;
+ set_a_dir( save);
+ if (sep == EOS)
+ break;
+ save = ++p;
+ }
+ while (*save == ENV_SEP)
+ ++save;
+ }
+ ACE_OS::free( save_start);
+}
+
+static void set_sys_dirs(
+ int set_cplus_dir /* Set C++ include-directory too */
+)
+/*
+ * Set site-specific and system-specific directories to the include directory
+ * list.
+ */
+{
+ if (cplus_val && set_cplus_dir) {
+#ifdef CPLUS_INCLUDE_DIR1
+ set_a_dir( CPLUS_INCLUDE_DIR1);
+#endif
+#ifdef CPLUS_INCLUDE_DIR2
+ set_a_dir( CPLUS_INCLUDE_DIR2);
+#endif
+#ifdef CPLUS_INCLUDE_DIR3
+ set_a_dir( CPLUS_INCLUDE_DIR3);
+#endif
+#ifdef CPLUS_INCLUDE_DIR4
+ set_a_dir( CPLUS_INCLUDE_DIR4);
+#endif
+ }
+
+#if SYS_FAMILY == SYS_UNIX
+ set_a_dir( "/usr/local/include");
+#endif
+
+#ifdef C_INCLUDE_DIR1
+ set_a_dir( C_INCLUDE_DIR1);
+#endif
+#ifdef C_INCLUDE_DIR2
+ set_a_dir( C_INCLUDE_DIR2);
+#endif
+
+#if SYS_FAMILY == SYS_UNIX
+#if SYSTEM == SYS_CYGWIN
+ if (no_cygwin) /* -mno-cygwin */
+ set_a_dir( "/usr/include/mingw");
+ else
+ set_a_dir( "/usr/include");
+#else
+ set_a_dir( "/usr/include"); /* Should be placed after C_INCLUDE_DIR? */
+#endif
+#endif
+}
+
+static void set_a_dir(
+ const char * dirname /* The path-name */
+)
+/*
+ * Append an include directory, checking array boundary.
+ * This routine is called from the following routines (in this order).
+ * 1. do_options() by -I option.
+ * 2. do_options() by -isystem option (for GNUC).
+ * 3. set_env_dirs() by environment variables.
+ * 4. set_sys_dirs() by CPLUS_INCLUDE_DIR?, C_INCLUDE_DIR? and system-
+ * specifics (unless -I- or -nostdinc option is specified).
+ * Note: a trailing PATH-DELIM is appended by norm_path().
+ */
+{
+ char * norm_name;
+ const char ** ip;
+
+ norm_name = norm_path( dirname, 0);
+ /* Normalize the pathname to compare */
+ for (ip = incdir; ip < incend; ip++) {
+ if (str_eq( *ip, norm_name)) {
+ ACE_OS::free( norm_name);
+ return;
+ }
+ }
+ if (& incdir[ NINCLUDE - 1] < incend)
+ cfatal( "Too many include directories %s" /* _F_ */
+ , norm_name, 0L, 0);
+ *incend++ = norm_name;
+}
+
+static char * norm_path(
+ const char * dir, /* Include directory (maybe a pointer to "") */
+ const char * fname /* Filename (possibly has directory part) */
+)
+/*
+ * Normalize the pathname removing redundant components such as
+ * "foo/../", "./" and trailing "/.".
+ * Append trailing "/" if 'fname' is 0.
+ * Change relative path to absolute path.
+ * Dereference a symbolic linked file (or directory) to a real directory/file.
+ * Returns a malloc'ed buffer.
+ * This routine is called from set_a_dir(), init_gcc_macro(), do_once() and
+ * open_file().
+ */
+{
+ char * norm_name;
+ char * start;
+ char * cp1;
+ char * cp2;
+ char * abs_path;
+ int len; /* Should not be size_t */
+ size_t start_pos = 0;
+ char slbuf1[ FILENAMEMAX+1];
+#if SYS_FAMILY == SYS_UNIX
+ char slbuf2[ FILENAMEMAX+1];
+#endif
+#if SYSTEM == SYS_CYGWIN || SYSTEM == SYS_MINGW
+ static char * root_dir;
+ static size_t root_dir_len;
+#if SYSTEM == SYS_CYGWIN
+ static char * cygdrive = "/cygdrive/";
+#else
+ static char * mingw_dir;
+ static size_t mingw_dir_len;
+#endif
+#endif
+
+ ACE_OS::strcpy( slbuf1, dir); /* Include directory */
+ len = ACE_OS::strlen( slbuf1);
+ if (len && slbuf1[ len - 1] != PATH_DELIM) {
+ slbuf1[ len] = PATH_DELIM; /* Append PATH_DELIM */
+ slbuf1[ len + 1] = EOS;
+ }
+#if SYS_FAMILY == SYS_UNIX
+ /* Dereference symbolic linked directory or file, if any */
+ slbuf2[ 0] = EOS;
+ if (*dir && ! fname) { /* Registering include directory */
+ /* Symbolic link check of directories are required */
+ deref_syml( slbuf1, slbuf2, slbuf1);
+ }
+ if (fname) {
+ len = ACE_OS::strlen( slbuf1);
+ ACE_OS::strcat( slbuf1, fname);
+ deref_syml( slbuf1, slbuf2, slbuf1 + len);
+ /* Symbolic link check of directory */
+ if ((len = ACE_OS::readlink( slbuf1, slbuf2, FILENAMEMAX)) > 0) {
+ /* Dereference symbolic linked file (not directory) */
+ *(slbuf2 + len) = EOS;
+ ACE_OS::strcpy( slbuf1, slbuf2);
+ }
+ }
+ if (mcpp_debug & PATH) {
+ if (slbuf2[ 0])
+ mcpp_fprintf( DBG, "Dereferenced \"%s%s\" to \"%s\"\n"
+ , dir, fname ? fname : "", slbuf1);
+ }
+#else
+ if (fname)
+ ACE_OS::strcat( slbuf1, fname);
+#endif
+ len = ACE_OS::strlen( slbuf1);
+ start = norm_name = xmalloc( len + 1); /* Need a new buffer */
+ ACE_OS::strcpy( norm_name, slbuf1);
+#if SYS_FAMILY == SYS_WIN
+ bsl2sl( norm_name);
+#endif
+#if FNAME_FOLD
+ conv_case( norm_name, norm_name + len, LOWER);
+#endif
+#if SPECIAL_PATH_DELIM /* ':' ? */
+ for (cp1 = norm_name; *cp1 != EOS; cp1++) {
+ if (*cp1 == PATH_DELIM)
+ *cp1 = '/';
+ }
+#endif
+ cp1 = norm_name;
+
+#if SYSTEM == SYS_CYGWIN
+ /* Convert to "/cygdirve/x/dir" style of absolute path-list */
+ if (ACE_OS::memcmp( cp1, "/usr/bin", 8) == 0 || ACE_OS::memcmp( cp1, "/usr/lib", 8) == 0) {
+ ACE_OS::memmove( cp1, cp1 + 4, len - 4 + 1); /* Remove "/usr" */
+ len -= 4;
+ }
+ if (*cp1 == '/' && ACE_OS::memcmp( cp1, cygdrive, 10) != 0) {
+ /* /dir, not /cygdrive/ */
+ if (! root_dir_len) { /* Should be initialized */
+ /* Convert "X:\DIR-list" to "/cygdrive/x/dir-list" */
+ root_dir = xmalloc( ACE_OS::strlen( CYGWIN_ROOT_DIRECTORY) + 1);
+ ACE_OS::strcpy( root_dir, CYGWIN_ROOT_DIRECTORY);
+ conv_case( root_dir, root_dir + ACE_OS::strlen( root_dir), LOWER);
+ *(root_dir + 1) = *root_dir; /* "x:/" to " x/" */
+ cp1 = xmalloc( ACE_OS::strlen( cygdrive) + ACE_OS::strlen( root_dir));
+ ACE_OS::strcpy( cp1, cygdrive);
+ ACE_OS::strcat( cp1, root_dir + 1);
+ ACE_OS::free( root_dir);
+ root_dir = cp1;
+ root_dir_len = ACE_OS::strlen( root_dir);
+ }
+ cp1 = xmalloc( root_dir_len + len + 1);
+ ACE_OS::strcpy( cp1, root_dir);
+ ACE_OS::strcat( cp1, norm_name); /* Convert to absolute path */
+ ACE_OS::free( norm_name);
+ norm_name = start = cp1;
+ len += root_dir_len;
+ }
+#endif
+
+#if SYSTEM == SYS_MINGW
+ /* Handle the mess of MinGW's path-list */
+ /* Convert to "x:/dir" style of absolute path-list */
+ if (*cp1 == PATH_DELIM && ACE_OS::isalpha( *(cp1 + 1))
+ && *(cp1 + 2) == PATH_DELIM) { /* /c/, /d/, etc*/
+ *cp1 = *(cp1 + 1);
+ *(cp1 + 1) = ':'; /* Convert to c:/, d:/, etc */
+ } else if (ACE_OS::memcmp( cp1, "/mingw", 6) == 0) {
+ if (! mingw_dir_len) { /* Should be initialized */
+ mingw_dir_len = ACE_OS::strlen( MINGW_DIRECTORY);
+ mingw_dir = xmalloc( mingw_dir_len + 1);
+ ACE_OS::strcpy( mingw_dir, MINGW_DIRECTORY);
+ conv_case( mingw_dir, mingw_dir + mingw_dir_len, LOWER);
+ }
+ cp1 = xmalloc( mingw_dir_len + len);
+ ACE_OS::strcpy( cp1, mingw_dir);
+ ACE_OS::strcat( cp1, norm_name + 6); /* Convert to absolute path */
+ ACE_OS::free( norm_name);
+ norm_name = start = cp1;
+ len += mingw_dir_len;
+ } else if (ACE_OS::memcmp( cp1, "/usr", 4) == 0) {
+ ACE_OS::memmove( cp1, cp1 + 4, len - 4 + 1); /* Remove "/usr" */
+ len -= 4;
+ }
+ if (*cp1 == '/') { /* /dir or / */
+ if (! root_dir_len) { /* Should be initialized */
+ root_dir_len = ACE_OS::strlen( MSYS_ROOT_DIRECTORY);
+ root_dir = xmalloc( root_dir_len + 1);
+ ACE_OS::strcpy( root_dir, MSYS_ROOT_DIRECTORY);
+ conv_case( root_dir, root_dir + root_dir_len, LOWER);
+ }
+ cp1 = xmalloc( root_dir_len + len + 1);
+ ACE_OS::strcpy( cp1, root_dir);
+ ACE_OS::strcat( cp1, norm_name); /* Convert to absolute path */
+ ACE_OS::free( norm_name);
+ norm_name = start = cp1;
+ len += root_dir_len;
+ }
+#endif
+
+#if SYS_FAMILY == SYS_WIN
+ if (*(cp1 + 1) == ':')
+ start = cp1 += 2; /* Skip the drive letter */
+ start_pos = 2;
+#endif
+ if (len == 1 && *norm_name == '/') /* Only "/" */
+ return norm_name;
+
+ if (ACE_OS::strncmp( cp1, "./", 2) == 0) /* Remove beginning "./" */
+ ACE_OS::memmove( cp1, cp1 + 2, ACE_OS::strlen( cp1 + 2) + 1); /* +1 for EOS */
+ if (*start != '/') { /* Relative path to current directory */
+ /* Make absolute path */
+ abs_path = xmalloc( len + ACE_OS::strlen( cur_work_dir) + 1);
+ cp1 = stpcpy( abs_path, cur_work_dir);
+ ACE_OS::strcpy( cp1, start);
+ ACE_OS::free( norm_name);
+ norm_name = abs_path;
+ start = cp1 = norm_name + start_pos;
+ }
+
+ while ((cp1 = ACE_OS::strstr( cp1, "/./")) != 0)
+ ACE_OS::memmove( cp1, cp1 + 2, ACE_OS::strlen( cp1 + 2) + 1);
+ /* Remove "/." of "/./" */
+ cp1 = start;
+ /* Remove redundant "foo/../" */
+ while ((cp1 = ACE_OS::strstr( cp1, "/../")) != 0) {
+ *cp1 = EOS;
+ if ((cp2 = ACE_OS::strrchr( start, '/')) != 0) {
+ if (*(cp1 - 1) != '.') {
+ ACE_OS::memmove( cp2 + 1, cp1 + 4, ACE_OS::strlen( cp1 + 4) + 1);
+ /* Remove "foo/../" */
+ cp1 = cp2;
+ } else { /* Impossible */
+ break;
+ }
+ } else { /* Impossible */
+ break;
+ }
+ }
+
+#if SPECIAL_PATH_DELIM
+ for (cp1 = start; *cp1 != EOS; cp1++) {
+ if (*cp1 == '/')
+ *cp1 = PATH_DELIM;
+ }
+#endif
+ if (mcpp_debug & PATH) {
+ char debug_buf[ FILENAMEMAX+1];
+ ACE_OS::strcpy( debug_buf, dir);
+ ACE_OS::strcat( debug_buf, fname ? fname : "");
+#if SYS_FAMILY == SYS_WIN
+ bsl2sl( debug_buf);
+#endif
+#if FNAME_FOLD
+ conv_case( debug_buf, debug_buf + ACE_OS::strlen( debug_buf), LOWER);
+#endif
+ if (! str_eq( debug_buf, norm_name))
+ mcpp_fprintf( DBG, "Normalized the path \"%s\" to \"%s\"\n"
+ , debug_buf, norm_name);
+ }
+
+ return norm_name;
+}
+
+#if SYS_FAMILY == SYS_UNIX
+
+static void deref_syml(
+ char * slbuf1,
+ char * slbuf2,
+ char * chk_start
+)
+/* Dereference symbolic linked directory */
+{
+ char * cp2;
+ int len; /* Should be int, not size_t */
+
+ while ((chk_start = ACE_OS::strchr( chk_start, PATH_DELIM)) != 0) {
+ *chk_start = EOS;
+ if ((len = ACE_OS::readlink( slbuf1, slbuf2, FILENAMEMAX)) > 0) {
+ /* Dereference symbolic linked directory */
+ cp2 = ACE_OS::strrchr( slbuf1, PATH_DELIM); /* Previous delimiter */
+ *chk_start = PATH_DELIM;
+ ACE_OS::strcpy( slbuf2 + len, chk_start);
+ if (slbuf2[ 0] == PATH_DELIM) { /* Absolute path */
+ ACE_OS::strcpy( slbuf1, slbuf2);
+ chk_start = slbuf1 + len + 1;
+ } else {
+ if (cp2)
+ chk_start = cp2 + 1;
+ else
+ chk_start = slbuf1;
+ ACE_OS::strcpy( chk_start, slbuf2); /* Rewrite the path */
+ chk_start += len;
+ }
+ } else {
+ *chk_start++ = PATH_DELIM;
+ }
+ }
+}
+#endif
+
+void conv_case(
+ char * name, /* (diretory) Name */
+ char * lim, /* End of (directory) name */
+ int upper /* TRUE if to upper */
+)
+/* Convert a string to upper-case letters or lower-case letters in-place */
+{
+ int c;
+ char * sp;
+
+ for (sp = name; sp < lim; sp++) {
+ c = *sp & UCHARMAX;
+#if MBCHAR
+ if ((char_type[ c] & mbstart)) {
+ char tmp[ FILENAMEMAX+1];
+ char * tp = tmp;
+ *tp++ = *sp++;
+ mb_read( c, &sp, &tp);
+ } else
+#endif
+ {
+ if (upper)
+ *sp = ACE_OS::ace_toupper( c);
+ else
+ *sp = ACE_OS::ace_tolower( c);
+ }
+ }
+}
+
+void put_info( void)
+/* Putout compiler-specific information */
+{
+#if COMPILER == GNUC
+ /*
+ * Putout the current directory as a #line line as:
+ * '# 1 "/abs-path/cur_dir//"'.
+ */
+ if (! put_info_done && ! no_output && gcc_work_dir)
+ mcpp_fprintf( OUT, "%s%ld \"%s%c\"\n"
+ , std_line_prefix ? "#line " : LINE_PREFIX
+ , src_line, cur_work_dir, '/');
+ put_info_done = TRUE;
+#endif
+}
+
+#if COMPILER == GNUC
+
+static DEFBUF * gcc_predef_std[ 128];
+static DEFBUF * gcc_predef_old[ 16];
+
+static void init_gcc_macro(
+ int gcc_maj_ver, /* __GNUC__ */
+ int gcc_min_ver /* __GNUC_MINOR__ */
+)
+/*
+ * Predefine GCC macros.
+ */
+{
+ char fname[ 256];
+ char * include_dir; /* The version-specific include directory */
+ char lbuf[ BUFSIZ];
+ FILE * fp;
+ DEFBUF ** predef;
+ DEFBUF * defp;
+ const char * cp;
+ char * tp;
+ int i;
+
+#if SYSTEM == SYS_CYGWIN
+ char mingw_dir[ FILENAMEMAX];
+
+ if (no_cygwin) {
+ include_dir = mingw_dir;
+ ACE_OS::sprintf( include_dir, "%s/%s", C_INCLUDE_DIR1, "mingw");
+ } else {
+ include_dir = C_INCLUDE_DIR1;
+ }
+#elif SYSTEM == SYS_MINGW
+ include_dir = C_INCLUDE_DIR2;
+ /* MinGW's 2nd directory is the version-specific one */
+#else
+#ifdef C_INCLUDE_DIR1
+ include_dir = C_INCLUDE_DIR1;
+#else
+ include_dir = "/usr/local/include";
+#endif
+#endif
+ include_dir = norm_path( include_dir, 0);
+
+ for (i = 0; i <= 1; i++) {
+ /* The predefined macro file */
+ cp = i ? "std" : "old";
+ ACE_OS::sprintf( fname, "%smcpp_g%s%d%d_predef_%s.h"
+ , include_dir, cplus_val ? "xx" : "cc"
+ , gcc_maj_ver, gcc_min_ver, cp);
+ /* Note that norm_path() append a PATH_DELIM. */
+ if ((fp = ACE_OS::fopen( fname, "r")) == 0) {
+ mcpp_fprintf( ERR, "Predefined macro file '%s' is not found\n"
+ , fname);
+ continue;
+ }
+ predef = i ? gcc_predef_std : gcc_predef_old;
+ while (ACE_OS::fgets( lbuf, BUFSIZ, fp) != 0) {
+ unget_string( lbuf, "gcc_predefine");
+ if (skip_ws() == '#'
+ && scan_token( skip_ws(), (tp = work_buf, &tp), work_end)
+ == NAM
+ && str_eq( work_buf, "define")) {
+ defp = do_define( TRUE); /* Ignore re-definition */
+ if (defp->nargs >= DEF_NOARGS - 1)
+ *predef++ = defp; /* Register only non-Standard macros*/
+ }
+ skip_nl();
+ }
+ *predef = 0; /* Terminate the array */
+ }
+
+ if (look_id( "__OPTIMIZE__")) /* -O option is specified */
+ undefine( "__NO_INLINE__");
+ if (no_exceptions) /* -fno-exceptions option */
+ undefine( "__EXCEPTIONS");
+}
+
+static void undef_gcc_macro(
+ int clearall
+)
+/*
+ * Undefine GCC predefined macros.
+ */
+{
+ DEFBUF ** predef;
+
+ predef = gcc_predef_old;
+ while (*predef)
+ undefine( (*predef++)->name);
+ gcc_predef_old[ 0] = 0;
+ if (clearall) {
+ predef = gcc_predef_std;
+ while (*predef)
+ undefine( (*predef++)->name);
+ gcc_predef_std[ 0] = 0;
+ }
+}
+
+static void chk_env( void)
+/*
+ * Check the environment variables to specify output of dependency lines.
+ */
+{
+ char * env;
+ char * cp;
+
+ /* Output of dependency lines */
+ if ((env = ACE_OS::getenv( "DEPENDENCIES_OUTPUT")) == 0) {
+ if ((env = ACE_OS::getenv( "SUNPRO_DEPENDENCIES")) == 0)
+ return;
+ else
+ mkdep |= MD_SYSHEADER;
+ }
+ mkdep |= MD_MKDEP;
+ if ((cp = ACE_OS::ACE_OS::strchr( env, ' ')) != 0) {
+ *cp++ = EOS;
+ while (*cp == ' ')
+ cp++;
+ }
+ if (! mkdep_fp) /* Command line option precedes */
+ mkdep_fp = ACE_OS::ACE_OS::fopen( env, "a");
+ if (! mkdep_target)
+ mkdep_target = cp;
+}
+
+#elif COMPILER == MSC
+
+static void init_msc_macro(
+ int wchar_t_modified
+)
+{
+ DEFBUF * defp;
+ int i;
+
+ defp = look_id( "_MSC_VER");
+ i = ACE_OS::atoi( defp->repl);
+ if (i >= 1400) { /* _MSC_VER >= 1400 */
+ look_and_install( "_MT", DEF_NOARGS - 1, null, "1");
+ if (cplus_val && ! wchar_t_modified) {
+ /* -Zc:wchar_t- was not specified */
+ look_and_install( "_NATIVE_WCHAR_T_DEFINED", DEF_NOARGS - 1, null
+ , "1");
+ look_and_install( "_WCHAR_T_DEFINED", DEF_NOARGS - 1, null, "1");
+ }
+ }
+}
+
+#endif
+
+void put_depend(
+ const char * filename
+)
+/*
+ * Append a header name to the source file dependency line.
+ */
+{
+#define MAX_OUT_LEN 76 /* Maximum length of output line */
+#define MKDEP_MAXLEN (MKDEP_MAX * 0x200)
+ static char output[ MKDEP_MAXLEN]; /* File names */
+ static char * pos[ MKDEP_MAX]; /* Pointers to filenames */
+ static int pos_num; /* Index of pos[] */
+ static char * out_p; /* Pointer to output[] */
+ static FILE * fp; /* Path to output dependency line */
+ static size_t llen; /* Length of current physical output line */
+ char ** pos_pp; /* Pointer to pos */
+ size_t fnamlen; /* Length of filename */
+
+ if (fp == 0) { /* Main source file. Have to initialize. */
+ out_p = md_init( filename, output);
+ fp = mkdep_fp;
+ llen = ACE_OS::strlen( output);
+ pos_num = 0; /* Initialize for MCPP_LIB build */
+ } else if (filename == 0) { /* End of input */
+ out_p = stpcpy( out_p, "\n\n");
+ if (mkdep & MD_PHONY) {
+ /* Output the phony target line for each recorded header files. */
+ char * cp;
+ int c;
+
+ if (ACE_OS::strlen( output) * 2 + (pos_num * 2) >= MKDEP_MAXLEN) {
+ cerror( "Too long dependency line\n" /* _E_ */
+ , 0, 0L, 0);
+ if (fp == fp_out)
+ mcpp_fputs( output, OUT );
+ else
+ ACE_OS::fputs( output, fp);
+ return;
+ }
+ pos_num--;
+ for (pos_pp = &pos[ 0]; pos_pp <= &pos[ pos_num]; pos_pp++) {
+ if (pos_pp == &pos[ pos_num]) {
+ for (cp = *pos_pp; *cp != '\n'; cp++)
+ ;
+ c = '\n';
+ } else {
+ cp = *(pos_pp + 1) - 1;
+ while( *cp == ' ' || *cp == '\\' || *cp == '\n')
+ cp--;
+ c = *(++cp);
+ }
+ *cp = EOS;
+ out_p = stpcpy( out_p, *pos_pp);
+ out_p = stpcpy( out_p, ":\n\n");
+ *cp = c;
+ }
+ }
+ if (fp == fp_out) /* To the same path with normal preprocessing */
+ mcpp_fputs( output, OUT);
+ else /* To the file specified by -MF, -MD, -MMD options */
+ ACE_OS::fputs( output, fp);
+ fp = 0; /* Clear for the next call in MCPP_LIB build */
+ return;
+ }
+
+ fnamlen = ACE_OS::strlen( filename);
+ /* Check the recorded filename */
+ for (pos_pp = pos; pos_pp < &pos[ pos_num]; pos_pp++) {
+ if (ACE_OS::memcmp( *pos_pp, filename, fnamlen) == 0)
+ return; /* Already recorded filename */
+ }
+ /* Any new header. Append its name to output. */
+ if (llen + fnamlen > MAX_OUT_LEN) { /* Line is long */
+ out_p = stpcpy( out_p, " \\\n "); /* Fold it */
+ llen = 1;
+ }
+ llen += fnamlen + 1;
+ if (pos_num >= MKDEP_MAX
+ || out_p + fnamlen + 1 >= output + MKDEP_MAXLEN)
+ cfatal( "Too long dependency line: %s", output, 0L, 0);
+ *out_p++ = ' ';
+ pos[ pos_num++] = out_p;
+ out_p = stpcpy( out_p, filename);
+}
+
+static char * md_init(
+ const char * filename, /* The source file name */
+ char * output /* Output to dependency file */
+)
+/*
+ * Initialize output file and target.
+ */
+{
+ char prefix[ FILENAMEMAX];
+ char * cp = 0;
+ size_t len;
+ char * out_p;
+ const char * target = filename;
+ const char * cp0;
+
+ if (! mkdep_target || ! mkdep_fp) { /* Make target name */
+#ifdef PATH_DELIM
+ if ((cp0 = ACE_OS::strrchr( target, PATH_DELIM)) != 0)
+ target = cp0 + 1;
+#endif
+ if ((cp0 = ACE_OS::strrchr( target, '.')) == 0)
+ len = ACE_OS::strlen( target);
+ else
+ len = (size_t) (cp0 - target);
+ ACE_OS::memcpy( prefix, target, len);
+ cp = prefix + len;
+ *cp++ = '.';
+ }
+
+ if (! mkdep_fp) { /* Unless already opened by -MF, -MD, -MMD options */
+ if (mkdep & MD_FILE) {
+ ACE_OS::strcpy( cp, "d");
+ mkdep_fp = ACE_OS::fopen( prefix, "w");
+ } else {
+ mkdep_fp = fp_out; /* Output dependency line to normal output */
+ no_output++; /* Without normal output */
+ }
+ }
+
+ if (mkdep_target) { /* -MT or -MQ option is specified */
+ if (mkdep & MD_QUOTE) { /* 'Quote' $, \t and space */
+ out_p = md_quote( output);
+ } else {
+ out_p = stpcpy( output, mkdep_target);
+ }
+ } else {
+ ACE_OS::strcpy( cp, OBJEXT);
+ out_p = stpcpy( output, prefix);
+ }
+
+ *out_p++ = ':';
+ return out_p;
+}
+
+static char * md_quote(
+ char * output
+)
+/*
+ * 'Quote' $, tab and space.
+ * This function was wretten referring to GCC V.3.2 source.
+ */
+{
+ char * p;
+ char * q;
+
+ for (p = mkdep_target; *p; p++, output++) {
+ switch (*p) {
+ case ' ':
+ case '\t':
+ /* GNU-make treats backslash-space sequence peculiarly */
+ for (q = p - 1; mkdep_target <= q && *q == '\\'; q--)
+ *output++ = '\\';
+ *output++ = '\\';
+ break;
+ case '$':
+ *output++ = '$';
+ break;
+ default:
+ break;
+ }
+ *output = *p;
+ }
+ *output = EOS;
+ return output;
+}
+
+static const char * toolong_fname =
+ "Too long header name \"%s%.0ld%s\""; /* _F_ */
+static const char * excess_token =
+ "Excessive token sequence \"%s\""; /* _E_, _W1_ */
+
+int do_include(
+ int next /* TRUE if the directive is #include_next */
+)
+/*
+ * Process the #include line.
+ * There are three variations:
+ * #include "file" search somewhere relative to the
+ * current (or source) directory, if not
+ * found, treat as #include <file>.
+ * #include <file> Search in an implementation-dependent
+ * list of places.
+ * #include macro-call Expand the macro call, it must be one of
+ * "file" or <file>, process as such.
+ * On success : return TRUE;
+ * On failure of syntax : return FALSE;
+ * On failure of file opening : return FALSE.
+ * do_include() always absorbs the line (including the <newline>).
+ */
+{
+ const char * const no_name = "No header name"; /* _E_ */
+ char header[ FILENAMEMAX + 16];
+ int token_type;
+ char * fname;
+ int delim; /* " or <, > */
+
+ if ((delim = skip_ws()) == '\n') { /* No argument */
+ cerror( no_name, 0, 0L, 0);
+ return FALSE;
+ }
+ fname = infile->bptr - 1; /* Current token for diagnosis */
+
+ if (standard && char_type[ delim] & LET) { /* Maybe a macro */
+ int c;
+ char *hp;
+
+ hp = header;
+ c = delim;
+ while (get_unexpandable( c, FALSE) != NO_TOKEN) {
+ /* Expand any macros in the line */
+ if (header + FILENAMEMAX < hp + (int) (workp - work_buf))
+ cfatal( toolong_fname, header, 0L, work_buf);
+ hp = stpcpy( hp, work_buf);
+ while ((c = get_ch()) == ' ')
+ *hp++ = ' ';
+ }
+ *hp = EOS; /* Ensure to terminate */
+ if (macro_line == MACRO_ERROR) /* Unterminated macro */
+ return FALSE; /* already diagnosed. */
+ unget_string( header, 0); /* To re-read */
+ delim = skip_ws();
+ if (delim == '\n') {
+ cerror( no_name, 0, 0L, 0); /* Expanded to */
+ return FALSE; /* 0 token. */
+ }
+ }
+
+ token_type = scan_token( delim, (workp = work_buf, &workp)
+ , work_buf + FILENAMEMAX);
+ if (token_type == STR) /* String literal form */
+ goto found_name;
+ else if (token_type == OPE && openum == OP_LT) /* '<' */
+ workp = scan_quote( delim, work_buf, work_buf + FILENAMEMAX, TRUE);
+ /* Re-construct or diagnose */
+ else /* Any other token in- */
+ goto not_header; /* cluding <=, <<, <% */
+
+ if (workp == 0) /* Missing closing '>' */
+ goto syntax_error;
+
+found_name:
+ *--workp = EOS; /* Remove the closing and */
+ fname = save_string( &work_buf[ 1]); /* the starting delimiter. */
+
+ if (skip_ws() != '\n') {
+ if (standard) {
+ cerror( excess_token, infile->bptr-1, 0L, 0);
+ skip_nl();
+ goto error;
+ } else if (mcpp_mode == OLD_PREP) {
+ skip_nl();
+ } else {
+ if (warn_level & 1)
+ cwarn( excess_token, infile->bptr-1, 0L, 0);
+ skip_nl();
+ }
+ }
+
+ if (open_include( fname, (delim == '"'), next)) {
+ goto opened;
+ }
+
+ cerror( "Can't open include file \"%s\"", fname, 0L, 0); /* _E_ */
+ goto error;
+
+not_header:
+ cerror( "Not a header name \"%s\"", fname, 0L, 0); /* _E_ */
+syntax_error:
+ skip_nl();
+ return FALSE;
+error:
+ ACE_OS::free( fname);
+ return FALSE;
+opened:
+ ACE_OS::free( fname);
+ errno = 0; /* Clear errno possibly set by path searching */
+ return TRUE;
+}
+
+static int open_include(
+ char * filename, /* File name to include */
+ int searchlocal, /* TRUE if #include "file" */
+ int next /* TRUE if #include_next */
+)
+/*
+ * Open an include file. This routine is only called from do_include()
+ * above, but was written as a separate subroutine for portability.
+ * It searches the list of directories via search_dir() and opens the file
+ * via open_file(), linking it into the list of active files.
+ * Returns TRUE if the file was opened, FALSE if open_file() fails.
+ */
+{
+ int full_path; /* Filename is full-path-list */
+ int has_dir = FALSE; /* Includer has directory part */
+ char dir[ FILENAMEMAX] = { EOS, }; /* Directory part of includer */
+
+#if SYS_FAMILY == SYS_WIN
+ bsl2sl( filename);
+#endif
+#if FNAME_FOLD /* If O.S. folds upper and lower cases of file-name */
+ /* Convert filename to lower-case-letters */
+ conv_case( filename, filename + ACE_OS::strlen( filename), LOWER);
+#endif
+
+#if SYS_FAMILY == SYS_UNIX
+ if (filename[0] == PATH_DELIM)
+#elif SYS_FAMILY == SYS_WIN
+ if (filename[1] == ':' && filename[2] == PATH_DELIM)
+#elif SYSTEM == SYS_MAC /* I don't know. Write by yourself */
+ if (filename[0] != PATH_DELIM && ACE_OS::strchr( filename, PATH_DELIM))
+#elif 1
+/* For other systems you should write code here. */
+ if (filename[0] == PATH_DELIM)
+#endif
+ full_path = TRUE;
+ else
+ full_path = FALSE;
+
+ if (!full_path && searchlocal && (search_rule & SOURCE))
+ has_dir = has_directory( infile->real_fname, dir)
+ || (**(infile->dirp) != EOS);
+
+#if COMPILER == GNUC
+ if (!full_path) {
+ if ((!searchlocal && incdir < sys_dirp) /* -I- option is specified */
+ || next) /* #include_next */
+ goto search_dirs;
+ }
+#endif
+
+ if (mcpp_debug & PATH)
+ mcpp_fprintf( DBG, "filename:%s\n", filename);
+ if ((searchlocal && ((search_rule & CURRENT) || !has_dir)) || full_path) {
+ /*
+ * Look in local directory first.
+ * Try to open filename relative to the "current directory".
+ */
+ if (open_file( &null, filename, searchlocal && !full_path))
+ return TRUE;
+ }
+ if (full_path)
+ return FALSE;
+
+ if (searchlocal && (search_rule & SOURCE) && has_dir) {
+ /*
+ * Look in local directory of source file.
+ * Try to open filename relative to the "source directory".
+ */
+ ACE_OS::strcat( dir, filename);
+ if (open_file( infile->dirp, dir, TRUE))
+ return TRUE;
+ }
+
+ /* Search the system include directories */
+#if COMPILER == GNUC
+search_dirs:
+#endif
+ if (search_dir( filename, searchlocal, next))
+ return TRUE;
+
+ return FALSE;
+}
+
+static int has_directory(
+ const char * source, /* Filename to examine */
+ char * directory /* Put directory stuff here */
+)
+/*
+ * If a directory is found in the 'source' filename string (i.e. "includer"),
+ * the directory part of the string is copied to 'directory' and
+ * has_directory() returns TRUE.
+ * Else, nothing is copied and it returns FALSE.
+ */
+{
+ const char * sp;
+ size_t len;
+
+ if ((sp = ACE_OS::strrchr( source, PATH_DELIM)) == 0) {
+ return FALSE;
+ } else {
+ len = (size_t)(sp - source) + 1;
+ ACE_OS::memcpy( directory, source, len);
+ directory[ len] = EOS;
+ return TRUE;
+ }
+}
+
+static int search_dir(
+ char * filename, /* File name to include */
+ int , /* #include "header.h" for GNUC */
+ int /* TRUE if #include_next */
+)
+/*
+ * Look in any directories specified by -I command line arguments,
+ * specified by environment variable, then in the builtin search list.
+ */
+{
+ const char ** incptr; /* -> inlcude directory */
+
+#if COMPILER == GNUC
+ if (next && **inc_dirp != EOS) {
+ incptr = inc_dirp + 1;
+ /* In case of include_next search after the includer's directory */
+ } else {
+ /* If (next && **inc_dirp == EOS), it should be #include_next "header.h"*/
+ if (searchlocal || next)
+ /* #include_next does not distinguish "header.h" and <header.h> */
+ incptr = incdir;
+ else
+ incptr = sys_dirp;
+ }
+#else
+ incptr = incdir;
+#endif
+
+ for ( ; incptr < incend; incptr++) {
+ if (ACE_OS::strlen( *incptr) + ACE_OS::strlen( filename) >= FILENAMEMAX) {
+ char * cp;
+ cp = stpcpy( work_buf, *incptr);
+ ACE_OS::strcpy( cp, filename);
+ cfatal( toolong_fname, work_buf, 0L, ""); /* _F_ */
+ }
+ if (open_file( incptr, filename, FALSE))
+ /* Now infile has been renewed */
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int open_file(
+ const char ** dirp, /* Pointer to directory */
+ const char * filename, /* The filename */
+ int local /* #include "file" */
+)
+/*
+ * Open a file, add it to the linked list of open files, close the includer
+ * if nessesary and truncate the includer's buffer.
+ * This is called from open_include() and at_start().
+ */
+{
+#if HOST_COMPILER == BORLANDC
+ /* Borland's ACE_OS::fopen() fails to set errno to EMFILE. */
+ static int max_open = ACE_OS::FOPEN_MAX - 5;
+#else
+ static int max_open;
+#endif
+ int len;
+ FILEINFO * file = infile;
+ FILE * fp;
+ char * cp;
+ char fullname[ FILENAMEMAX + 1];
+
+ if (mcpp_debug & PATH)
+ mcpp_fprintf( DBG, "Searching %s\n", **dirp == EOS ? "." : *dirp);
+ if (standard && included( *dirp, filename)) /* Once included */
+ return TRUE;
+ cp = stpcpy( fullname, *dirp);
+ ACE_OS::strcat( cp, filename);
+
+ if ((max_open != 0 && max_open <= include_nest)
+ /* Exceed the known limit of open files */
+ || ((fp = ACE_OS::fopen( fullname, "r")) == 0 && errno == EMFILE)) {
+ /* Reached the limit for the first time */
+ /*
+ * Table of open files is full.
+ * Remember the file position and close the includer.
+ * The state will be restored by get_line() on end of the included.
+ */
+ file->pos = ACE_OS::ftell( file->fp);
+ ACE_OS::fclose( file->fp);
+ /* In case of failure, re-open the includer */
+ if ((fp = ACE_OS::fopen( fullname, "r")) == 0) {
+ file->fp = ACE_OS::fopen( cur_fullname, "r");
+ ACE_OS::fseek( file->fp, file->pos, SEEK_SET);
+ return FALSE;
+ }
+ if (max_open == 0) /* Remember the limit of the system */
+ max_open = include_nest;
+ } else if (fp == 0) { /* No file, illegal path name or so */
+ return FALSE;
+ }
+ /* Truncate buffer of the includer to save memory */
+ len = (int) (file->bptr - file->buffer);
+ if (len) {
+ file->buffer = xrealloc( file->buffer, len + 1);
+ file->bptr = file->buffer + len;
+ }
+
+ if (mkdep && ((mkdep & MD_SYSHEADER) || local))
+ put_depend( fullname); /* Output dependency line */
+
+ add_file( fp, filename); /* Add file-info to the linked list */
+ /*
+ * Remember the directory for #include_next.
+ * Note: inc_dirp is restored to the parent includer's directory
+ * by get_ch() when the current includer is finished.
+ */
+ infile->dirp = inc_dirp = dirp;
+ ACE_OS::strcpy( cur_fullname, fullname);
+
+ if (zflag) {
+ no_output++; /* Don't output the included file */
+ } else {
+ src_line = 1; /* Working on line 1 now */
+ sharp(); /* Print out the included file name */
+ }
+ src_line = 0; /* To read the first line */
+ return TRUE;
+}
+
+void add_file(
+ FILE * fp, /* Open file pointer */
+ const char * filename /* Name of the file */
+)
+/*
+ * Initialize tables for this open file. This is called from open_file()
+ * (for #include files), and from the entry to MCPP to open the main input
+ * file. It calls a common routine get_file() to build the FILEINFO
+ * structure which is used to read characters.
+ */
+{
+ FILEINFO * file;
+ const char * too_many_include_nest =
+ "More than %.0s%ld nesting of #include"; /* _F_ _W4_ */
+
+ filename = set_fname( filename); /* Search or append to fnamelist[] */
+ file = get_file( filename, (size_t) NBUFF); /* file == infile */
+ file->fp = fp; /* Better remember FILE * */
+ cur_fname = filename;
+
+ if (include_nest >= INCLUDE_NEST) /* Probably recursive #include */
+ cfatal( too_many_include_nest, 0, (long) INCLUDE_NEST, 0);
+ if (standard && (warn_level & 4) && include_nest == inc_nest_min + 1)
+ cwarn( too_many_include_nest, 0, (long) inc_nest_min, 0);
+ include_nest++;
+}
+
+static const char * set_fname(
+ const char * filename
+)
+/*
+ * Register the source filename to fnamelist[].
+ * Search fnamelist[] for filename or append filename to fnamelist[].
+ * Returns the pointer.
+ */
+{
+ const char ** fnamep;
+
+ /* Register the filename in fnamelist[] */
+ fnamep = fnamelist;
+ while (fnamep < fname_end) {
+ if (str_eq( *fnamep, filename)) /* Already registered */
+ break;
+ fnamep++;
+ }
+ if (fnamep < fname_end) {
+ filename = *fnamep;
+ } else {
+ if (fname_end - fnamelist >= FNAMELIST)
+ cfatal( "Too many include files", 0, 0L, 0); /* _F_ */
+ *fname_end = xmalloc( ACE_OS::strlen( filename) + 1);
+ filename = ACE_OS::strcpy( *(char **)fname_end++, filename);
+ /* Global pointer for get_file() */
+ }
+ return filename;
+}
+
+void cur_file( void)
+/*
+ * Output current source file name.
+ */
+{
+ FILEINFO * file = infile;
+ const char * name;
+ char * cp;
+
+ while (file->fp == 0)
+ file = file->parent;
+ cp = stpcpy( work_buf, *(file->dirp));
+ ACE_OS::strcpy( cp, file->filename);
+ name = work_buf;
+ if (sharp_filename == 0 || ! str_eq( name, sharp_filename)) {
+ if (sharp_filename != 0)
+ ACE_OS::free( sharp_filename);
+ sharp_filename = save_string( name);
+ }
+ if (! no_output)
+ mcpp_fprintf( OUT, " \"%s\"", name);
+#if COMPILER == GNUC
+ if (sys_dirp <= file->dirp && file->dirp <= incend)
+ mcpp_fputs( " 3", OUT);
+#endif
+}
+
+#if SYS_FAMILY == SYS_WIN
+
+static char * bsl2sl(
+ char * filename
+)
+/*
+ * Convert '\\' in the path-list to '/'.
+ */
+{
+ static int diagnosed = FALSE;
+ char * cp;
+
+ cp = filename;
+
+ while (*cp) {
+ if (bsl_in_mbchar) {
+ int c;
+ c = *cp & UCHARMAX;
+ if (char_type[ c] & mbstart) { /* First byte of MBCHAR */
+ char tmp[ FILENAMEMAX];
+ char * tp = tmp;
+ *tp++ = *cp++;
+ mb_read( c, &cp, &tp);
+ /* Read over the multi-byte characters */
+ continue;
+ }
+ }
+ if (*cp == '\\') {
+ *cp++ = PATH_DELIM;
+ if (!diagnosed && (warn_level & 2) && (warn_level != -1)) {
+ /* Backslash in source program */
+ cwarn(
+ "Converted \\ to %s", "/", 0L, 0); /* _W2_ */
+ diagnosed = TRUE; /* Diagnose only once */
+ }
+ } else {
+ cp++;
+ }
+ }
+
+ return filename;
+}
+
+#endif /* SYS_FAMILY == SYS_WIN */
+
+static const char * const unknown_arg =
+ "Unknown argument \"%s\""; /*_W1_*/
+static const char * const not_ident =
+ "Not an identifier \"%s\""; /*_W1_*/
+
+static int is_junk( void)
+/*
+ * Check the trailing junk in a directive line.
+ * This routine is never called in OLD_PREP mode.
+ */
+{
+ int c;
+
+ c = skip_ws();
+ unget_ch();
+ if (c != '\n') { /* Trailing junk */
+ if (warn_level & 1)
+ cwarn( unknown_arg, infile->bptr, 0L, 0);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+#define PUSH 1
+#define POP -1
+
+#define __SETLOCALE 1 /* #pragma __setlocale( "encoding") */
+#define SETLOCALE 2 /* #pragma setlocale( "encoding") */
+
+void do_pragma( void)
+/*
+ * Process the #pragma lines.
+ * 1. Process the sub-directive for MCPP.
+ * 2. Pass the line to the compiler-proper.
+ * #pragma MCPP put_defines, #pragma MCPP preprocess,
+ * #pragma MCPP preprocessed and #pragma once are, however, not put
+ * out so as not to duplicate output when re-preprocessed.
+ * When EXPAND_PRAGMA == TRUE and (__STDC_VERSION__ >= 199901L or
+ * __cplusplus >= 199901L), the line is subject to macro expansion unless
+ * the next to 'pragma' token is one of 'STDC', 'GCC' or 'MCPP'.
+ */
+{
+ int c;
+ int warn = FALSE; /* Necessity of warning */
+ int token_type;
+ char * bp; /* Pointer to argument */
+ char * tp;
+ FILEINFO * file;
+
+ wrong_line = TRUE; /* In case of error */
+ c = skip_ws();
+ bp = infile->bptr - 1; /* Remember token to pass to compiler */
+ if (c == '\n') {
+ if (warn_level & 1)
+ cwarn( "No sub-directive", 0, 0L, 0); /* _W1_ */
+ unget_ch();
+ return;
+ }
+ token_type = scan_token( c, (tp = work_buf, &tp), work_end);
+#if EXPAND_PRAGMA
+#if COMPILER == MSC
+ if (token_type == NAM
+ && !str_eq( identifier, "STDC") && !str_eq( identifier, "MCPP")) {
+#else
+ if (stdc3 && token_type == NAM
+ && !str_eq( identifier, "STDC") && !str_eq( identifier, "MCPP")) {
+#endif
+ DEFBUF * defp;
+ char * mp;
+ char * mp_end;
+
+ bp = mp = xmalloc( (size_t)(NMACWORK + IDMAX));
+ /* Buffer for macro expansion */
+ mp_end = mp + NMACWORK;
+ tp = stpcpy( mp, identifier);
+ do { /* Expand all the macros in the line */
+ if (token_type == NAM && (defp = is_macro( &tp)) != 0) {
+ tp = expand_macro( defp, bp, mp_end);
+ if (! stdc3 && (warn_level & 2))
+ cwarn(
+ "\"%s\" is macro expanded in other than C99 mode" /* _W2_ */
+ , identifier, 0L, 0);
+ }
+ token_type = scan_token( c = get_ch(), (bp = tp, &tp), mp_end);
+ } while (c != '\n');
+ unget_string( mp, 0); /* To re-read */
+ ACE_OS::free( mp);
+ c = skip_ws();
+ bp = infile->bptr - 1;
+ token_type = scan_token( c, (tp = work_buf, &tp), work_end);
+ }
+#endif
+ if (token_type != NAM) {
+ if (warn_level & 1)
+ cwarn( not_ident, work_buf, 0L, 0);
+ goto skip_nl;
+ } else if (str_eq( identifier, "once")) { /* #pragma once */
+ if (! is_junk()) {
+ file = infile;
+ while (file->fp == 0)
+ file = file->parent;
+ do_once( *(file->dirp), file->real_fname);
+ goto skip_nl;
+ }
+ } else if (str_eq( identifier, "MCPP")) {
+ if (scan_token( skip_ws(), (tp = work_buf, &tp), work_end) != NAM) {
+ if (warn_level & 1)
+ cwarn( not_ident, work_buf, 0L, 0);
+ }
+ if (str_eq( identifier, "put_defines")) {
+ if (! is_junk())
+ dump_def( dDflag, TRUE); /* #pragma MCPP put_defines */
+ } else if (str_eq( identifier, "preprocess")) {
+ if (! is_junk()) /* #pragma MCPP preprocess */
+ mcpp_fputs( "#pragma MCPP preprocessed\n", OUT);
+ /* Just putout the directive */
+ } else if (str_eq( identifier, "preprocessed")) {
+ if (! is_junk()) { /* #pragma MCPP preprocessed*/
+ skip_nl();
+ do_preprocessed();
+ return;
+ }
+ } else if (str_eq( identifier, "warning")) {
+ /* #pragma MCPP warning */
+ cwarn( infile->buffer, 0, 0L, 0);
+ } else if (str_eq( identifier, "push_macro")) {
+ push_or_pop( PUSH); /* #pragma MCPP push_macro */
+ } else if (str_eq( identifier, "pop_macro")) {
+ push_or_pop( POP); /* #pragma MCPP pop_macro */
+ } else if (str_eq( identifier, "debug")) {
+ do_debug( TRUE); /* #pragma MCPP debug */
+ } else if (str_eq( identifier, "end_debug")) {
+ do_debug( FALSE); /* #pragma MCPP end_debug */
+ } else {
+ warn = TRUE;
+ }
+ if (warn && (warn_level & 1))
+ cwarn( unknown_arg, identifier, 0L, 0);
+ goto skip_nl; /* Do not putout the line */
+#if COMPILER == GNUC
+ /* The #pragma lines for GCC is skipped not to confuse cc1. */
+ } else if (str_eq( identifier, "GCC")) { /* #pragma GCC * */
+ if ((scan_token( skip_ws(), (tp = work_buf, &tp), work_end) == NAM)
+ && (str_eq( identifier, "poison")
+ || str_eq( identifier, "dependency")
+ || str_eq( identifier, "system_header"))) {
+ if (warn_level & 2)
+ cwarn( "Skipped the #pragma line" /*_W2_ */
+ , 0, 0L, 0);
+ goto skip_nl;
+ }
+#endif
+
+#if COMPILER == MSC
+ } else if (str_eq( identifier, "setlocale")) {
+ if (skip_ws() == '('
+ && scan_token( skip_ws(), (tp = work_buf, &tp), work_end)
+ == STR
+ && skip_ws() == ')') {
+ if (! is_junk()) {
+ work_buf[ 0] = *(tp - 1) = '\0';
+ set_encoding( work_buf + 1, 0, SETLOCALE);
+ work_buf[ 0] = *(tp - 1) = '"';
+ } /* else warned by is_junk() */
+ } else {
+ warn = TRUE;
+ }
+#else /* COMPILER != MSC */
+ } else if (str_eq( identifier, "__setlocale")) {
+ if (skip_ws() == '('
+ && scan_token( skip_ws(), (tp = work_buf, &tp), work_end)
+ == STR
+ && skip_ws() == ')') {
+ if (! is_junk()) { /* #pragma __setlocale */
+ work_buf[ 0] = *(tp - 1) = '\0';
+ set_encoding( work_buf + 1, 0, __SETLOCALE);
+ work_buf[ 0] = *(tp - 1) = '"';
+ } /* else warned by is_junk() */
+ } else {
+ warn = TRUE;
+ }
+#endif
+
+#if COMPILER == MSC
+ } else if (str_eq( identifier, "push_macro")) {
+ push_or_pop( PUSH);
+ goto skip_nl;
+ } else if (str_eq( identifier, "pop_macro")) {
+ push_or_pop( POP);
+ goto skip_nl;
+#endif
+
+#if COMPILER == LCC
+ } else if (str_eq( identifier, "optimize")
+ && (skip_ws() == '(')
+ && (char_type[ (c = skip_ws()) & UCHARMAX] == DIG)
+ && (skip_ws() == ')')) {
+ char tmp[ 2];
+
+ tmp[ 0] = c;
+ tmp[ 1] = EOS;
+ look_and_install( optim_name, DEF_NOARGS - 1, null, tmp);
+#endif
+
+#if COMPILER == COMPILER_UNKNOWN
+ /*
+ * Write here any compiler-specific #pragma sub-directive which should
+ * be processed by preprocessor.
+ */
+#endif
+ }
+
+ if (warn) {
+ if (warn_level & 1)
+ cwarn( unknown_arg, identifier, 0L, 0);
+ goto skip_nl; /* Do not putout the line */
+ }
+
+ sharp(); /* Synchronize line number before output */
+ if (! no_output) {
+ mcpp_fputs( "#pragma ", OUT);
+ mcpp_fputs( bp, OUT); /* Line is put out */
+ }
+skip_nl: /* Don't use skip_nl() which skips to the newline in source file */
+ while (get_ch() != '\n')
+ ;
+}
+
+static void do_once(
+ const char * dir,
+ const char * filename
+)
+/*
+ * Process #pragma MCPP once or #pragma once so as not to re-include the file
+ * in future.
+ * This directive has been imported from GCC V.1.* / cpp as an extension.
+ */
+{
+ INC_LIST * inc;
+ size_t fnamlen;
+
+ filename = norm_path( dir, filename); /* Normalize path name */
+ fnamlen = ACE_OS::strlen( filename);
+ inc = (INC_LIST *) xmalloc( sizeof (INC_LIST) + fnamlen + 1);
+ ACE_OS::memcpy( inc->fname, filename, fnamlen + 1);
+ ACE_OS::free( (void *) filename);
+ inc->next = 0;
+ if (start_inc == 0)
+ start_inc = last_inc = inc; /* The first file */
+ else
+ last_inc = last_inc->next = inc; /* Append the file to the list */
+}
+
+static int included(
+ const char * dir,
+ const char * filename
+)
+/*
+ * Has the file been once included ?
+ * This routine is called only from open_file().
+ */
+{
+ INC_LIST * inc;
+ char * fname;
+
+ fname = norm_path( dir, filename);
+ for (inc = start_inc; inc; inc = inc->next) {
+ if (str_eq( inc->fname, fname)) {
+ /* Already included */
+ if (mcpp_debug & PATH)
+ mcpp_fprintf( DBG, "Once included \"%s\"\n", fname);
+ ACE_OS::free( fname);
+ return TRUE;
+ }
+ }
+ ACE_OS::free( fname);
+ return FALSE; /* Not yet included */
+}
+
+static void push_or_pop(
+ int direction
+)
+/* Process #pragma MCPP push_macro( "MACRO"),
+ * #pragma MCPP pop_macro( "MACRO") for other compilers than Visual C,
+ * and #pragma push_macro( "MACRO"), #pragma pop_macro( "MACRO") for Visual C.
+ * Note:1. "push" count is set in defp->push.
+ * 2. pushed definitions are inserted immediatly after the current
+ * definition of the same name.
+ * 3. the definitions of a same name macro can be pushed multiple times.
+ */
+{
+ char * tp;
+ DEFBUF ** prevp;
+ DEFBUF * defp;
+ DEFBUF * dp;
+ int cmp;
+ size_t s_name, s_def;
+
+ if (skip_ws() == '('
+ && scan_token( skip_ws(), (tp = work_buf, &tp), work_end) == STR
+ && skip_ws() == ')') { /* Correct syntax */
+
+ if (is_junk())
+ return;
+ s_name = ACE_OS::strlen( work_buf) - 2;
+ *(work_buf + s_name + 1) = '\0';
+ ACE_OS::memcpy( identifier, work_buf + 1, s_name + 1);
+ /* Remove enclosing '"' */
+ prevp = look_prev( identifier, &cmp);
+ if (cmp == 0) { /* Current definition or pushed definition exists */
+ defp = *prevp;
+ if (direction == PUSH) {/* #pragma push_macro( "MACRO") */
+ if (defp->push) { /* No current definition*/
+ if (warn_level & 1)
+ cwarn( "\"%s\" is already pushed" /* _W1_ */
+ , identifier, 0L, 0);
+ return;
+ }
+ /* Else the current definition exists. Push it */
+ s_def = sizeof (DEFBUF) + 3 + s_name
+ + ACE_OS::strlen( defp->repl) + ACE_OS::strlen( defp->fname);
+ if (mcpp_mode == STD)
+ s_def += ACE_OS::strlen( defp->parmnames);
+ dp = (DEFBUF *) xmalloc( s_def);
+ ACE_OS::memcpy( dp, defp, s_def); /* Copy the definition */
+ dp->link = *prevp; /* Insert to linked-list*/
+ *prevp = dp; /* the pushed def */
+ prevp = &dp->link; /* Next link to search */
+ } else { /* #pragma pop_macro( "MACRO") */
+ if (defp->push == 0) { /* Current definition */
+ if (defp->link == 0
+ || ! str_eq( identifier, defp->link->name)) {
+ if (warn_level & 1)
+ cwarn( "\"%s\" has not been pushed" /* _W1_ */
+ , identifier, 0L, 0);
+ return;
+ } else {
+ *prevp = defp->link;
+ /* Link the previous and the next */
+ ACE_OS::free( defp);
+ /* Delete the definition to enable popped def */
+ }
+ } /* Else no current definition exists */
+ }
+ while ((defp = *prevp) != 0) {
+ /* Increment or decrement "push" count of all pushed defs */
+ if ((cmp = ACE_OS::memcmp( defp->name, identifier, s_name)) > 0)
+ break;
+ defp->push += direction; /* Increment or decrement */
+ prevp = &defp->link;
+ }
+ } else { /* No current definition nor pushed definition */
+ if (warn_level & 1)
+ cwarn( "\"%s\" has not been defined" /* _W1_ */
+ , identifier, 0L, 0);
+ }
+ } else { /* Wrong syntax */
+ if (warn_level & 1)
+ cwarn( "Bad %s syntax", direction == PUSH /* _W1_ */
+ ? "push_macro" : "pop_macro", 0L, 0);
+ }
+}
+
+static void do_asm(
+ int asm_start /* #asm ? */
+)
+/*
+ * #asm, #endasm
+ * Originally written for OS-9/09 Microware C.
+ */
+{
+ if (! compiling)
+ return;
+ if (asm_start == (in_asm != 0L)) {
+ if (in_asm)
+ cerror( "In #asm block started at line %.0s%ld" /* _E_ */
+ , 0, in_asm, 0);
+ else
+ cerror( "Without #asm", 0, 0L, 0); /* _E_ */
+ skip_nl();
+ unget_ch();
+ return;
+ }
+ in_asm = asm_start ? src_line : 0L;
+}
+
+void do_old( void)
+/*
+ * Process the out-of-standard directives.
+ * GCC permits #include_next and #warning even in STANDARD mode.
+ */
+{
+ static const char * const unknown
+ = "Unknown #directive \"%s\"%.0ld%s"; /* _E_ _W8_ */
+
+#if COMPILER == GNUC
+ static const char * const gnu_ext
+ = "%s is not allowed by Standard%.0ld%s"; /* _W2_ _W8_*/
+
+ if (str_eq( identifier, "include_next")) {
+ if ((compiling && (warn_level & 2))
+ || (! compiling && warn_level & 8))
+ cwarn( gnu_ext, "#include_next", 0L
+ , compiling ? 0 : " (in skipped block)");
+ if (! compiling)
+ return;
+ in_include = TRUE;
+ do_include( TRUE);
+ in_include = FALSE;
+ return;
+ } else if (str_eq( identifier, "warning")) {
+ if ((compiling && (warn_level & 2))
+ || (! compiling && warn_level & 8))
+ cwarn( gnu_ext, "#warning", 0L
+ , compiling ? 0 : " (in skipped block)");
+ if (! compiling)
+ return;
+ cwarn( infile->buffer, 0, 0L, 0);
+ /* Always output the warning */
+ skip_nl();
+ unget_ch();
+ return;
+ } else if (str_eq( identifier, "ident") || str_eq( identifier, "sccs")) {
+ if ((compiling && (warn_level & 1))
+ || (! compiling && warn_level & 8)) {
+ if (str_eq( identifier, "ident"))
+ cwarn(
+ compiling ? "Ignored #ident" : "#ident (in skipped block)" /* _W1_ _W8_*/
+ , 0, 0L, 0);
+ else
+ cwarn(
+ compiling ? "Ignored #sccs" : "#sccs (in skipped block)" /* _W1_ _W8_*/
+ , 0, 0L, 0);
+ }
+ if (! compiling)
+ return;
+ skip_nl();
+ unget_ch();
+ return;
+ }
+#endif /* COMPILER == GNUC */
+
+#if COMPILER == MSC
+ if (str_eq( identifier, "using") || str_eq( identifier, "import")) {
+ /* #using or #import */
+ if (! compiling)
+ return;
+ mcpp_fputs( infile->buffer, OUT); /* Putout the line as is*/
+ skip_nl();
+ unget_ch();
+ return;
+ }
+#endif
+
+ if (! standard && do_prestd_directive())
+ return;
+
+ if (compiling) {
+ if (lang_asm) { /* "Assembler" source */
+ if (warn_level & 1)
+ cwarn( unknown, identifier, 0L, 0);
+ mcpp_fputs( infile->buffer, OUT); /* Putout the line */
+ } else {
+ cerror( unknown, identifier, 0L, 0);
+ }
+ } else if (warn_level & 8) {
+ cwarn( unknown, identifier, 0L, " (in skipped block)");
+ }
+ skip_nl();
+ unget_ch();
+ return;
+}
+
+static int do_prestd_directive( void)
+/*
+ * Process directives for pre-Standard mode.
+ */
+{
+#if COMPILER != GNUC
+ if (str_eq( identifier, "assert")) { /* #assert */
+ if (! compiling) /* Only validity check */
+ return TRUE;
+ if (eval_if() == 0L) { /* Assert expression */
+ cerror( "Preprocessing assertion failed" /* _E_ */
+ , 0, 0L, 0);
+ skip_nl();
+ unget_ch();
+ }
+ return TRUE;
+ } else
+#endif
+ if (str_eq( identifier, "put_defines")) {
+ if (! compiling) /* Only validity check */
+ return TRUE;
+ if (mcpp_mode != OLD_PREP && ! is_junk())
+ dump_def( dDflag, TRUE); /* #put_defines */
+ skip_nl();
+ unget_ch();
+ return TRUE;
+ } else if (str_eq( identifier, "preprocess")) {
+ if (! compiling) /* Only validity check */
+ return TRUE;
+ if (mcpp_mode != OLD_PREP && ! is_junk())
+ /* Just putout the directive for the succeding preprocessor */
+ mcpp_fputs( "#preprocessed\n", OUT);
+ skip_nl();
+ unget_ch();
+ return TRUE;
+ } else if (str_eq( identifier, "preprocessed")) {
+ if (! compiling) /* Only validity check */
+ return TRUE;
+ if (mcpp_mode != OLD_PREP && ! is_junk()) {
+ skip_nl();
+ do_preprocessed(); /* #preprocessed */
+ return TRUE;
+ }
+ skip_nl();
+ unget_ch();
+ return TRUE;
+ }
+
+ if (str_eq( identifier, "debug")) { /* #debug <args> */
+ if (! compiling) /* Only validity check */
+ return TRUE;
+ do_debug( TRUE);
+ return TRUE;
+ } else if (str_eq( identifier, "end_debug")) {
+ if (! compiling)
+ return TRUE;
+ do_debug( FALSE); /* #end_debug <args> */
+ return TRUE;
+ }
+
+ if (str_eq( identifier, "asm")) { /* #asm */
+ do_asm( TRUE);
+ return TRUE;
+ }
+ if (str_eq( identifier, "endasm")) { /* #endasm */
+ do_asm( FALSE);
+ skip_nl(); /* Skip comments, etc. */
+ unget_ch();
+ return TRUE;
+ }
+
+ return FALSE; /* Unknown directive */
+}
+
+static void do_preprocessed( void)
+/*
+ * The source file has been already preprocessed.
+ * Copy the lines to output.
+ * Install macros according the #define directives.
+ */
+{
+ const char * corrupted =
+ "This preprocessed file is corrupted"; /* _F_ */
+ FILEINFO * file;
+ char * lbuf;
+ char * cp;
+ const char ** incptr;
+ char * comment = 0;
+ char * colon = 0;
+ const char * dir;
+#if STD_LINE_PREFIX == FALSE
+ char conv[ NBUFF];
+ char * arg;
+
+ /*
+ * Compiler cannot accept C source style #line.
+ * Convert it to the compiler-specific format.
+ */
+ ACE_OS::strcpy( conv, LINE_PREFIX);
+ arg = conv + ACE_OS::strlen( conv);
+#endif
+ file = infile;
+ lbuf = file->bptr = file->buffer; /* Reset file->bptr */
+
+ /* Copy the input to output until a comment line appears. */
+ while (ACE_OS::fgets( lbuf, NBUFF, file->fp) != 0
+ && ACE_OS::memcmp( lbuf, "/*", 2) != 0) {
+#if STD_LINE_PREFIX == FALSE
+ if (ACE_OS::memcmp( lbuf, "#line ", 6) == 0) {
+ ACE_OS::strcpy( arg, lbuf + 6);
+ mcpp_fputs( conv, OUT);
+ } else
+#endif
+ {
+ mcpp_fputs( lbuf, OUT);
+ }
+ }
+ if (! str_eq( lbuf, "/* Currently defined macros. */\n"))
+ cfatal( "This is not a preprocessed source" /* _F_ */
+ , 0, 0L, 0);
+
+ /* Define macros according to the #define lines. */
+ while (ACE_OS::fgets( lbuf, NWORK, file->fp) != 0) {
+ if (ACE_OS::memcmp( lbuf, "/*", 2) == 0) {
+ /* Standard predefined macro */
+ continue;
+ } else {
+ if (ACE_OS::memcmp( lbuf, "#define ", 8) != 0) {
+ if (ACE_OS::memcmp( lbuf, "#line", 5) == 0)
+ continue;
+ else
+ cfatal( corrupted, 0, 0L, 0);
+ }
+ /* Filename and line-number information in comment as: */
+ /* dir/fname:1234\t*/
+ cp = lbuf + ACE_OS::strlen( lbuf);
+ if ((ACE_OS::memcmp( cp - 4, "\t*/\n", 4) != 0)
+ || (*(cp - 4) = EOS
+ , (comment = ACE_OS::strrchr( lbuf, '*')) == 0)
+ || (ACE_OS::memcmp( --comment, "/* ", 3) != 0)
+ || ((colon = ACE_OS::strrchr( comment, ':')) == 0))
+ cfatal( corrupted, 0, 0L, 0);
+ src_line = atol( colon + 1); /* Pseudo line number */
+ *colon = EOS;
+ dir = comment + 3;
+ inc_dirp = &null;
+ /* Search the include directory list */
+ for (incptr = incdir ; incptr < incend; incptr++) {
+ if (ACE_OS::memcmp( *incptr, dir, ACE_OS::strlen( *incptr)) == 0) {
+ inc_dirp = incptr;
+ break;
+ }
+ }
+ /* Register the filename to fnamelist[] */
+ /* inc_dirp may be 0, and cur_fname may be "(predefined)" */
+ cur_fname = set_fname( dir + ACE_OS::strlen( *inc_dirp));
+ ACE_OS::strcpy( comment - 2, "\n"); /* Remove the comment */
+ unget_string( lbuf + 8, 0);
+ do_define( FALSE);
+ get_ch(); /* '\n' */
+ get_ch(); /* Clear the "file" */
+ unget_ch(); /* infile == file */
+ }
+ }
+ file->bptr = file->buffer + ACE_OS::strlen( file->buffer);
+}
+
+static int do_debug(
+ int set /* TRUE to set debugging */
+)
+/*
+ * #pragma MCPP debug, #pragma MCPP end_debug, #debug, #end_debug
+ * Return TRUE when diagnostic is issued else return FALSE.
+ */
+{
+ struct Debug_arg {
+ const char * arg_name; /* Name of option */
+ int arg_num; /* Value of 'debug' */
+ };
+ static struct Debug_arg debug_args[] = {
+ { "path", PATH },
+ { "token", TOKEN },
+ { "expand", EXPAND },
+ { "if", IF },
+ { "expression", EXPRESSION },
+ { "getc", GETC },
+ { "memory", MEMORY },
+ { 0, 0 },
+ };
+ struct Debug_arg *argp;
+ int num;
+ int c;
+
+ c = skip_ws();
+ if (c == '\n') {
+ unget_ch();
+ if (set) {
+ if (warn_level & 1)
+ cwarn( "No argument", 0, 0L, 0); /* _W1_ */
+ return TRUE;
+ } else {
+ mcpp_debug = 0; /* Clear all the flags */
+ return FALSE;
+ }
+ }
+ while (scan_token( c, (workp = work_buf, &workp), work_end) == NAM) {
+ argp = debug_args;
+ while (argp->arg_name) {
+ if (str_eq( argp->arg_name, work_buf))
+ break;
+ argp++;
+ }
+ if (argp->arg_name == 0) {
+ if (warn_level & 1)
+ cwarn( unknown_arg, work_buf, 0L, 0);
+ goto diagnosed;
+ } else {
+ num = argp->arg_num;
+ if (set) {
+ mcpp_debug |= num;
+ if (num == PATH)
+ dump_path();
+ else if (num == MEMORY)
+ print_heap();
+ } else {
+ mcpp_debug &= ~num;
+ }
+ }
+ c = skip_ws();
+ }
+ if (c != '\n') {
+ if (warn_level & 1)
+ cwarn( not_ident, work_buf, 0L, 0);
+ skip_nl();
+ unget_ch();
+ goto diagnosed;
+ }
+ unget_ch();
+ return FALSE;
+diagnosed:
+ return TRUE;
+}
+
+void put_asm( void)
+/*
+ * Put out source line as it is.
+ */
+{
+#if 0
+ mcpp_fputs( "#2\n", OUT);
+ mcpp_fputs( infile->buffer, OUT);
+ skip_nl();
+#endif
+}
+
+static void dump_path( void)
+/*
+ * Show the include directories.
+ */
+{
+ const char ** incptr;
+ const char * inc_dir;
+ const char * dir = "./";
+
+ mcpp_fputs( "Include paths are as follows --\n", DBG);
+ for (incptr = incdir; incptr < incend; incptr++) {
+ inc_dir = *incptr;
+ if (*inc_dir == '\0')
+ inc_dir = dir;
+ mcpp_fprintf( DBG, " %s\n", inc_dir);
+ }
+ mcpp_fputs( "End of include path list.\n", DBG);
+}
+
+/*
+ * list_heap() is a function to print out information of heap-memory.
+ * See "kmmalloc-2.5.1.lzh" by kmatsui.
+ */
+#if KMMALLOC
+ int list_heap( int);
+#elif BSD_MALLOC
+ int list_heap( char *);
+#elif DB_MALLOC || DMALLOC
+ int list_heap( FILE *);
+#endif
+
+void print_heap( void)
+{
+#if KMMALLOC
+ list_heap( 1);
+#elif BSD_MALLOC
+ list_heap( ":cpp");
+#elif DB_MALLOC || DMALLOC || PHK_MALLOC || DLMALLOC
+ list_heap( fp_debug);
+#endif
+}
+
+void at_end( void)
+/*
+ * Handle the commands to be executed at the end of processing.
+ */
+{
+#if COMPILER == GNUC
+ if (dMflag || dDflag) {
+ dump_def( dDflag, FALSE);
+ }
+#endif
+}
+
+#if MCPP_LIB
+void clear_filelist( void)
+/*
+ * Free malloced memory for filename-list and directory-list.
+ */
+{
+ const char ** namep;
+ INC_LIST * inc;
+ INC_LIST * pnext;
+
+ for (namep = fnamelist; namep < fname_end; namep++)
+ ACE_OS::free( (void*) *namep);
+
+ if (standard) {
+ for (inc = start_inc; inc != 0; inc = pnext) {
+ pnext = inc->next;
+ ACE_OS::free( inc);
+ }
+ start_inc = 0;
+ }
+
+ for (namep = incdir; namep < incend; namep++)
+ ACE_OS::free( (void *) *namep);
+}
+#endif
+
diff --git a/TAO/TAO_IDL/contrib/mcpp/testmain.cpp b/TAO/TAO_IDL/contrib/mcpp/testmain.cpp
new file mode 100644
index 00000000000..8a8469e0c7b
--- /dev/null
+++ b/TAO/TAO_IDL/contrib/mcpp/testmain.cpp
@@ -0,0 +1,77 @@
+/* $Id$
+ * testmain.c: A sample source to show how to use mcpp as a subroutine.
+ * 2006/11 Contributed by Juergen Mueller.
+ * Refer to mcpp-porting.html section 3.12 for compiling mcpp as a subroutine.
+ *
+ * 2007/03 Updated to enable testing of memory buffer output.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#define MCPP_LIB 1
+#include "mcpp_lib.h"
+
+int main(int argc, char *argv[])
+{
+ int i, j;
+ char ** tmp_argv;
+
+ tmp_argv = (char **) malloc(sizeof(char *) * (argc + 1));
+
+ if (tmp_argv == 0) {
+ return(0);
+ }
+
+ /*
+ * assume strict order: <options, ...> <files, ...> and
+ * each option and its argument are specified without intervening spaces
+ * such as '-I/dir' or '-otmp.i' (not '-I /dir' nor '-o tmp.i').
+ */
+ for (i = 0; i < argc; ++i) {
+ tmp_argv[i] = argv[i]; /* copy options */
+
+ if ( (*argv[i] != '-')
+ && (*argv[i] != '/')
+ && (i > 0)) {
+ break;
+ }
+ }
+
+ /* this works only if called function does not manipulate pointer array! */
+ for (j = i; i < argc; ++i) {
+ int retval;
+ char * result;
+ clock_t start, finish;
+
+ tmp_argv[j] = argv[i]; /* process each file */
+ ACE_OS::fprintf(stderr, "\n%s\n", argv[i]);
+ start = clock(); /* get start time */
+#if OUT2MEM /* Use memory buffer */
+ mcpp_use_mem_buffers( 1); /* enable memory output */
+ retval = mcpp_lib_main(j + 1, tmp_argv); /* call MCPP */
+ result = mcpp_get_mem_buffer( OUT); /* get the output */
+ if (result)
+ ACE_OS::fputs( result, stdout);
+ result = mcpp_get_mem_buffer( ERR); /* get the diagnostics */
+ if (result)
+ ACE_OS::fputs( result, stderr);
+#if 0 /* debug output is the same with normal output by default */
+ result = mcpp_get_mem_buffer( DBG); /* get the debug output */
+ if (result)
+ ACE_OS::fputs( result, stdout); /* appended to output */
+#endif
+#else /* Normal output to file */
+ retval = mcpp_lib_main(j + 1, tmp_argv);
+#endif
+ finish = clock(); /* get finish time */
+
+ ACE_OS::fprintf(stderr, "\nReturned status:%d, Elapsed time: %.3f seconds.\n",
+ retval, (double)(finish - start) / (double)CLOCKS_PER_SEC);
+ }
+
+ ACE_OS::free(tmp_argv);
+
+ return(0);
+}
diff --git a/TAO/TAO_IDL/driver/drv_mcpp_preproc.cpp b/TAO/TAO_IDL/driver/drv_mcpp_preproc.cpp
new file mode 100644
index 00000000000..28a19727e78
--- /dev/null
+++ b/TAO/TAO_IDL/driver/drv_mcpp_preproc.cpp
@@ -0,0 +1,1120 @@
+// $Id$
+
+/*
+
+COPYRIGHT
+
+Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United
+States of America. All Rights Reserved.
+
+This product is protected by copyright and distributed under the following
+license restricting its use.
+
+The Interface Definition Language Compiler Front End (CFE) is made
+available for your use provided that you include this license and copyright
+notice on all media and documentation and the software program in which
+this product is incorporated in whole or part. You may copy and extend
+functionality (but may not remove functionality) of the Interface
+Definition Language CFE without charge, but you are not authorized to
+license or distribute it to anyone else except as part of a product or
+program developed by you or with the express written consent of Sun
+Microsystems, Inc. ("Sun").
+
+The names of Sun Microsystems, Inc. and any of its subsidiaries or
+affiliates may not be used in advertising or publicity pertaining to
+distribution of Interface Definition Language CFE as permitted herein.
+
+This license is effective until terminated by Sun for failure to comply
+with this license. Upon termination, you shall destroy or return all code
+and documentation for the Interface Definition Language CFE.
+
+INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF
+ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS
+FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF
+DEALING, USAGE OR TRADE PRACTICE.
+
+INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT
+ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES
+TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT.
+
+SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH
+RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY
+INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF.
+
+IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR
+ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL
+DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+Use, duplication, or disclosure by the government is subject to
+restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
+Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR
+52.227-19.
+
+Sun, Sun Microsystems and the Sun logo are trademarks or registered
+trademarks of Sun Microsystems, Inc.
+
+SunSoft, Inc.
+2550 Garcia Avenue
+Mountain View, California 94043
+
+NOTE:
+
+SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are
+trademarks or registered trademarks of Sun Microsystems, Inc.
+
+*/
+
+// Pass an IDL file through the C preprocessor
+
+
+#include "idl_defines.h"
+#include "global_extern.h"
+#include "fe_extern.h"
+#include "drv_extern.h"
+#include "utl_string.h"
+#include "ace/Version.h"
+#include "ace/Process_Manager.h"
+#include "ace/SString.h"
+#include "ace/Env_Value_T.h"
+#include "ace/ARGV.h"
+#include "ace/UUID.h"
+#include "ace/Dirent.h"
+#include "ace/OS_NS_sys_stat.h"
+
+// FUZZ: disable check_for_streams_include
+#include "ace/streams.h"
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_fcntl.h"
+
+#include "mcpp_lib.h"
+
+ACE_RCSID (driver,
+ drv_preproc,
+ "$Id$")
+
+// Storage for preprocessor args.
+unsigned long const DRV_MAX_ARGCOUNT = 128;
+unsigned long DRV_argcount = 0;
+char const * DRV_arglist[DRV_MAX_ARGCOUNT] = { 0 };
+
+static char const * output_arg_format = 0;
+static long output_arg_index = 0;
+
+char const DIR_DOT[] = ".";
+char const DIR_DOT_DOT[] = "..";
+
+// File names.
+static char tmp_file [MAXPATHLEN + 1] = { 0 };
+
+// Lines can be 1024 chars long intially - it will expand as required.
+#define LINEBUF_SIZE 1024
+char* drv_line = 0;
+static size_t drv_line_size = LINEBUF_SIZE + 1;
+
+// Push the new CPP location if we got a -Yp argument.
+void
+DRV_cpp_new_location (char const * new_loc)
+{
+ ACE::strdelete (const_cast<char *> (DRV_arglist[0]));
+ DRV_arglist[0] = ACE::strnew (new_loc);
+}
+
+// Push an argument into the DRV_arglist.
+void
+DRV_cpp_putarg (const char *str)
+{
+ if (DRV_argcount >= DRV_MAX_ARGCOUNT)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s%s %d %s\n",
+ idl_global->prog_name (),
+ ": More than",
+ DRV_MAX_ARGCOUNT,
+ "arguments to preprocessor"));
+
+ throw Bailout ();
+ }
+
+ DRV_arglist[DRV_argcount++] = ACE::strnew (str);
+}
+
+// Expand the output argument with the given filename.
+void
+DRV_cpp_expand_output_arg (const char *filename)
+{
+ if (output_arg_format != 0)
+ {
+ ACE::strdelete (const_cast<char *> (DRV_arglist[output_arg_index]));
+ DRV_arglist[output_arg_index] = 0;
+
+ char *output_arg = 0;
+ ACE_NEW (output_arg,
+ char [ACE_OS::strlen (output_arg_format)
+ + ACE_OS::strlen (filename)
+ + 1]);
+
+ ACE_OS::sprintf (output_arg,
+ output_arg_format,
+ filename);
+
+ DRV_arglist[output_arg_index] = output_arg;
+ }
+}
+
+// Get a line from stdin.
+static bool
+DRV_get_line (FILE *f)
+{
+ char *l = ACE_OS::fgets (drv_line,
+ drv_line_size,
+ f);
+
+ if (l == 0)
+ {
+ return false;
+ }
+
+ if (*l == '\0' && feof (f))
+ {
+ return false;
+ }
+
+ if (*l == '\0')
+ {
+ return true;
+ }
+
+ while (ACE_OS::strchr (drv_line, '\n') == 0)
+ {
+ // Haven't got to a newline yet.
+ // Create a bigger buffer and keep reading.
+ size_t temp_size;
+ temp_size = drv_line_size * 2;
+ char *temp = 0;
+ ACE_NEW_RETURN (temp,
+ char[temp_size],
+ false);
+ ACE_OS::strcpy (temp, drv_line);
+ delete [] drv_line;
+ drv_line = temp;
+ drv_line_size = temp_size;
+
+ l = ACE_OS::fgets (drv_line + ACE_OS::strlen (drv_line),
+ drv_line_size - ACE_OS::strlen(drv_line),
+ f);
+
+ if (l == 0 || *l == '\0')
+ {
+ break;
+ }
+ }
+
+ size_t i = ACE_OS::strlen (drv_line) - 1;
+
+ if (drv_line[i] == '\n')
+ {
+ drv_line[i] = '\0';
+ }
+
+ return true;
+}
+
+// Initialize the cpp argument list.
+void
+DRV_cpp_init (void)
+{
+ // Create the line buffer.
+ // (JP) Deleting this at the end or DRV_pre_proc() causes
+ // Purify to output a Freeing Mismatched Memory warning.
+ // When it is not deleted (currently the case) there is no
+ // memory leak reported by Purify. I don't know why.
+ ACE_NEW (drv_line,
+ char [drv_line_size]);
+
+ char const * const cpp_loc = FE_get_cpp_loc_from_env ();
+ DRV_cpp_putarg (cpp_loc);
+
+ // Add an option to the IDL compiler to make the TAO version
+ // available to the user. A XX.YY.ZZ release gets version 0xXXYYZZ,
+ // for example, 5.1.14 gets 0x050114.
+ char version_option[128];
+ ACE_OS::sprintf (version_option,
+ "-D__TAO_IDL=0x%2.2d%2.2d%2.2d",
+ ACE_MAJOR_VERSION,
+ ACE_MINOR_VERSION,
+ ACE_BETA_VERSION);
+
+ DRV_cpp_putarg (version_option);
+ DRV_cpp_putarg ("-I.");
+
+ const char *platform_cpp_args = FE_get_cpp_args_from_env ();
+
+ if (platform_cpp_args == 0)
+ {
+ // If no cpp flag was defined by the user, we define some
+ // platform specific flags here.
+
+#if defined (TAO_IDL_PREPROCESSOR_ARGS)
+ platform_cpp_args = TAO_IDL_PREPROCESSOR_ARGS;
+#elif defined (ACE_CC_PREPROCESSOR_ARGS)
+ platform_cpp_args = ACE_CC_PREPROCESSOR_ARGS;
+#else
+ platform_cpp_args = "-o %s";
+#endif /* TAO_IDL_PREPROCESSOR_ARGS */
+
+ // So we can find OMG IDL files, such as `orb.idl'.
+ ACE_CString include_path1, include_path2;
+
+ char* TAO_ROOT = ACE_OS::getenv ("TAO_ROOT");
+
+ // When adding new dirs here don't forget to update
+ // IDL_GlobalData::validate_orb_include accordingly.
+ if (TAO_ROOT != 0)
+ {
+ DRV_add_include_path (include_path1, TAO_ROOT, 0);
+ DRV_add_include_path (include_path2, TAO_ROOT, "/tao");
+ }
+ else
+ {
+ char* ACE_ROOT = ACE_OS::getenv ("ACE_ROOT");
+
+ if (ACE_ROOT != 0)
+ {
+ DRV_add_include_path (include_path1, ACE_ROOT, "/TAO");
+ DRV_add_include_path (include_path2, ACE_ROOT, "/TAO/tao");
+ }
+ else
+ {
+#if defined (TAO_IDL_INCLUDE_DIR)
+ // TAO_IDL_INCLUDE_DIR may be in quotes,
+ // e.g. "/usr/local/include/tao"
+ // We deal with a case like this below ...
+ DRV_add_include_path (include_path1, TAO_IDL_INCLUDE_DIR, 0);
+ DRV_add_include_path (include_path2, ".", 0);
+#else
+ DRV_add_include_path (include_path1, ".", 0);
+#endif /* TAO_IDL_INCLUDE_DIR */
+ }
+ }
+
+ idl_global->tao_root (include_path1.c_str ());
+ }
+
+ // Add any flags in platform_cpp_args to cpp's DRV_arglist.
+ ACE_ARGV platform_arglist (platform_cpp_args);
+
+ for (int i = 0; i < platform_arglist.argc (); ++i)
+ {
+ // Check for an argument that specifies the preprocessor's output file.
+ if (ACE_OS::strstr (platform_arglist[i], "%s") != 0
+ && output_arg_format == 0)
+ {
+ output_arg_format = ACE::strnew (platform_arglist[i]);
+ output_arg_index = DRV_argcount;
+ DRV_cpp_putarg (0);
+ }
+ else
+ {
+ DRV_cpp_putarg (platform_arglist[i]);
+ }
+ }
+}
+
+int
+DRV_sweep_dirs (const char *rel_path,
+ const char *base_path)
+{
+ // Zero rel_path means we're not using this option, and
+ // so we become a no-op.
+ if (rel_path == 0)
+ {
+ return 0;
+ }
+
+ if (ACE_OS::chdir (rel_path) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "DRV_sweep_dirs: chdir %s failed\n",
+ rel_path),
+ -1);
+ }
+
+ ACE_Dirent dir (DIR_DOT);
+ ACE_CString bname (base_path);
+ bname += (bname.length () > 0 ? "/" : "");
+ bname += rel_path;
+ bool include_added = false;
+ char abspath[MAXPATHLEN] = "";
+ char *full_path = 0;
+
+ for (dirent *dir_entry; (dir_entry = dir.read ()) != 0;)
+ {
+ // Skip the ".." and "." files in each directory.
+ if (ACE_OS::strcmp (dir_entry->d_name, DIR_DOT) == 0
+ || ACE_OS::strcmp (dir_entry->d_name, DIR_DOT_DOT) == 0)
+ {
+ continue;
+ }
+
+ ACE_CString lname (dir_entry->d_name);
+ ACE_stat stat_buf;
+
+ if (ACE_OS::lstat (lname.c_str (), &stat_buf) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "DRV_sweep_dirs: ACE_OS::lstat (%s) failed\n",
+ lname.c_str ()),
+ -1);
+ }
+
+ size_t len = 0;
+
+ switch (stat_buf.st_mode & S_IFMT)
+ {
+ case S_IFREG: // Either a regular file or an executable.
+ len = lname.length ();
+
+ if (len > 4 && lname.substr (len - 4) == ".idl")
+ {
+ if (!include_added)
+ {
+ ACE_CString incl_arg ("-I");
+ incl_arg += bname;
+ DRV_cpp_putarg (incl_arg.c_str ());
+ idl_global->add_rel_include_path (bname.c_str ());
+ full_path = ACE_OS::realpath ("", abspath);
+
+ if (full_path != 0)
+ {
+ idl_global->add_include_path (full_path);
+ }
+
+ include_added = true;
+ }
+
+ ACE_CString fname (bname);
+ fname += "/";
+ fname += lname;
+ DRV_push_file (fname.c_str ());
+ }
+
+ break;
+ case S_IFDIR: // Subdirectory.
+ DRV_sweep_dirs (lname.c_str (), bname.c_str ());
+ break;
+ case S_IFLNK: // Either a file link or directory link.
+ default: // Some other type of file (PIPE/FIFO/device).
+ break;
+ }
+ }
+
+ // Move back up a level.
+ if (ACE_OS::chdir (DIR_DOT_DOT) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "DRV_sweep_dirs: chdir .. (from %s) failed\n",
+ rel_path),
+ -1);
+ }
+
+ return 0;
+}
+
+ACE_CString&
+DRV_add_include_path (ACE_CString& include_path, const char* p, const char* suffix)
+{
+ if (p == 0) return include_path;
+
+ ACE_CString include_option ("-I");
+
+ size_t len = ACE_OS::strlen (p);
+
+ bool quote = !(p[0] == '"' || ACE_OS::strchr (p, ' ') == 0);
+
+ // Eliminate possible quotes from the path
+ if ('"' == p[0])
+ {
+ include_path = p + 1;
+ include_path[len - 2] = 0;
+ }
+ else
+ {
+ include_path = p;
+ }
+
+ // Some compilers choke on "//" separators.
+ if (p[len - 1] == '/' || p[len - 1] == '\\')
+ {
+ include_path[len - 1] = '\0';
+ }
+
+ for ( ; suffix != 0 && *suffix != 0; suffix++)
+ {
+#if defined (ACE_WIN32)
+ if (*suffix == '/')
+ include_path += '\\';
+#else
+ if (*suffix == '\\')
+ include_path += '/';
+#endif
+ else
+ include_path += *suffix;
+ }
+
+ if (quote)
+ include_option += '"';
+
+ include_option += include_path; //.c_str ();
+
+ if (quote)
+ include_option += '"';
+
+ DRV_cpp_putarg (include_option.c_str ());
+ idl_global->add_include_path (include_path.c_str ());
+
+ return include_path;
+}
+
+// Adds additional include paths, but after parse_args() has
+// added user-defined include paths.
+void
+DRV_cpp_post_init (void)
+{
+
+ // Add include path for TAO_ROOT/orbsvcs.
+ char* TAO_ROOT = ACE_OS::getenv ("TAO_ROOT");
+
+ ACE_CString include_path3, include_path4, include_path5;
+
+ // When adding new dirs here don't forget to update
+ // IDL_GlobalData::validate_orb_include accordingly.
+ if (TAO_ROOT != 0)
+ {
+ DRV_add_include_path (include_path3, TAO_ROOT, "/orbsvcs");
+ }
+ else
+ {
+ // If TAO_ROOT isn't defined, assume it's under ACE_ROOT.
+ char* ACE_ROOT = ACE_OS::getenv ("ACE_ROOT");
+
+ if (ACE_ROOT != 0)
+ {
+ DRV_add_include_path (include_path3, TAO_ROOT, "/TAO/orbsvcs");
+ }
+ else
+ {
+ // If ACE_ROOT isn't defined either, there will already
+ // be a warning from DRV_preproc().
+ DRV_add_include_path (include_path3, ".", 0);
+ }
+ }
+
+ // Add include paths for CIAO_ROOT and CIAO_ROOT/ciao.
+ char* CIAO_ROOT = ACE_OS::getenv ("CIAO_ROOT");
+
+ if (CIAO_ROOT != 0)
+ {
+ DRV_add_include_path (include_path4, CIAO_ROOT, 0);
+ DRV_add_include_path (include_path5, CIAO_ROOT, "/ciao");
+ }
+ else if (TAO_ROOT != 0)
+ {
+ // If CIAO_ROOT hasn't been set, maybe it's nested under TAO_ROOT.
+ DRV_add_include_path (include_path4, TAO_ROOT, "/CIAO");
+ DRV_add_include_path (include_path5, TAO_ROOT, "/CIAO/ciao");
+ }
+ else
+ {
+ // If TAO_ROOT hasn't been set, try ACE_ROOT.
+ char* ACE_ROOT = ACE_OS::getenv ("ACE_ROOT");
+
+ if (ACE_ROOT != 0)
+ {
+ DRV_add_include_path (include_path4, ACE_ROOT, "/TAO/CIAO");
+ DRV_add_include_path (include_path5, ACE_ROOT, "/TAO/CIAO/ciao");
+ }
+ else
+ {
+ // If ACE_ROOT isn't defined either, there will already
+ // be a warning from DRV_preproc().
+ DRV_add_include_path (include_path4, ACE_ROOT, ".");
+ DRV_add_include_path (include_path5, ACE_ROOT, ".");
+ }
+ }
+
+ // Save path of current directory, in case the call to DRV_sweep_dirs()
+ // below is not a no-op - then the current working directory will
+ // have to be restored.
+ char cwd_path[MAXPATHLEN];
+ if (ACE_OS::getcwd (cwd_path, sizeof (cwd_path)) == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "DRV_cpp_post_init: ACE_OS::getcwd failed\n"));
+
+ throw Bailout ();
+ }
+
+ // If first arg is non-zero, adds an include path and filename
+ // for every IDL file found in all subdirectories. This is a
+ // no-op for most backends.
+ if (DRV_sweep_dirs (idl_global->recursion_start (), "") == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "DRV_cpp_post_init: DRV_sweep_dirs (%s) failed\n",
+ idl_global->recursion_start ()));
+
+ throw Bailout ();
+ }
+
+ // This is redundant for most backends, but not if the call to
+ // DRV_sweep_dirs() above is more than a no-op.
+ if (ACE_OS::chdir (cwd_path) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "DRV_cpp_post_init: ACE_OS::chdir (%s) failed\n",
+ cwd_path));
+
+ throw Bailout ();
+ }
+}
+
+// We really need to know whether this line is a "#include ...". If
+// so, we would like to separate the "file name" and keep that in the
+// idl_global. We need them to produce "#include's in the stubs and
+// skeletons.
+void
+DRV_check_for_include (const char* buf)
+{
+ const char* r = buf;
+ const char* h;
+
+ // Skip the tabs and spaces.
+ while (*r == ' ' || *r == '\t')
+ {
+ ++r;
+ }
+
+ // Skip initial '#'.
+ if (*r != '#')
+ {
+ return;
+ }
+ else
+ {
+ r++;
+ }
+
+ // Skip the tabs and spaces.
+ while (*r == ' ' || *r == '\t')
+ {
+ ++r;
+ }
+
+ // Probably we are at the word `include`. If not return.
+ if (*r != 'i')
+ {
+ return;
+ }
+
+ // Check whether this word is `include` or no.
+ static const char include_str[] = "include";
+
+ for (size_t ii = 0;
+ ii < (sizeof (include_str) / sizeof (include_str[0]) - 1)
+ && *r != '\0' && *r != ' ' && *r != '\t';
+ ++r, ++ii)
+ {
+ // Return if it doesn't match.
+ if (include_str[ii] != *r)
+ {
+ return;
+ }
+ }
+
+ // Next thing is finding the file that has been `#include'd. Skip
+ // all the blanks and tabs and reach the startng " or < character.
+ for (; (*r != '"') && (*r != '<'); ++r)
+ {
+ if (*r == '\n' || *r == '\0')
+ {
+ return;
+ }
+ }
+
+ // Decide on the end char.
+ char end_char = '"';
+
+ if (*r == '<')
+ {
+ end_char = '>';
+ }
+
+ // Skip this " or <.
+ ++r;
+
+ // Store this position.
+ h = r;
+
+ // We're not handling redirection from stdin.
+ if (*h == '\0')
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO_IDL: No input files\n")));
+
+
+ throw Bailout ();
+ }
+
+ // Find the closing " or < character.
+ for (; *r != end_char; ++r)
+ {
+ continue;
+ }
+
+ // Copy the chars.
+ char incl_file[MAXPATHLEN + 1] = { 0 };
+ size_t fi = 0;
+
+ for (; h != r; ++fi, ++h)
+ {
+ incl_file [fi] = *h;
+ }
+
+ // Terminate the string.
+ incl_file [fi] = '\0';
+
+ // Put Microsoft-style pathnames into a canonical form.
+ size_t i = 0;
+
+ for (size_t j = 0; incl_file [j] != '\0'; ++i, ++j)
+ {
+ if (incl_file [j] == '\\' && incl_file [j + 1] == '\\')
+ {
+ j++;
+ }
+
+ incl_file [i] = incl_file [j];
+ }
+
+ // Terminate this string.
+ incl_file [i] = '\0';
+
+ size_t const len = ACE_OS::strlen (incl_file);
+ ACE_CString const name_str (incl_file);
+ ACE_CString const simple ("orb.idl");
+ ACE_CString const nix_path ("tao/orb.idl");
+ ACE_CString const win_path ("tao\\orb.idl");
+
+ // Some backends pass this file through, others don't.
+ if (name_str == simple || name_str == nix_path || name_str == win_path)
+ {
+ if (idl_global->pass_orb_idl ())
+ {
+ idl_global->add_to_included_idl_files (incl_file);
+ }
+ else
+ {
+ DRV_get_orb_idl_includes ();
+ }
+ }
+
+ // We have special lookup for orb.idl (TAO_ROOT/tao) that
+ // also kicks in for .pidl files. If one of the latter is
+ // included as a local name only, we add the 'tao/' prefix
+ // so the generated C++ include files will be correct.
+ else if (ACE_OS::strcmp (incl_file + len - 5, ".pidl") == 0
+ && ACE_OS::strchr (incl_file, '/') == 0
+ && ACE_OS::strchr (incl_file, '\\') == 0)
+ {
+ ACE_CString fixed_name ("tao/");
+ fixed_name += incl_file;
+
+ idl_global->add_to_included_idl_files (fixed_name.rep ());
+ }
+ else
+ {
+ idl_global->add_to_included_idl_files (incl_file);
+ }
+}
+
+// This method turns a line like '#include "a.idl"' into the
+// line '#include <a.idl>'
+void
+DRV_convert_includes (const char* buf)
+{
+ // Remove constness
+ char* r = const_cast<char*> (buf);
+
+ // Skip the tabs and spaces.
+ while (*r == ' ' || *r == '\t')
+ {
+ ++r;
+ }
+
+ // Skip initial '#'.
+ if (*r != '#')
+ {
+ return;
+ }
+ else
+ {
+ r++;
+ }
+
+ // Skip the tabs and spaces.
+ while (*r == ' ' || *r == '\t')
+ {
+ ++r;
+ }
+
+ // Probably we are at the word `include`. If not return.
+ if (*r != 'i')
+ {
+ return;
+ }
+
+ // Check whether this word is `include` or no.
+ static const char include_str[] = "include";
+
+ for (size_t ii = 0;
+ ii < (sizeof (include_str) / sizeof (include_str[0]) - 1)
+ && *r != '\0' && *r != ' ' && *r != '\t';
+ ++r, ++ii)
+ {
+ // Return if it doesn't match.
+ if (include_str[ii] != *r)
+ {
+ return;
+ }
+ }
+
+ // Next thing is finding the file that has been `#include'd. Skip
+ // all the blanks and tabs and reach the startng " character.
+ for (; (*r != '"'); ++r)
+ {
+ if (*r == '\n' || *r == '\0')
+ {
+ return;
+ }
+ }
+
+ // Replace the opening quote with an angle bracket.
+ *r = '<';
+
+ // We're not handling redirection from stdin.
+ if (*r == '\0')
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO_IDL: No input files\n")));
+
+
+ throw Bailout ();
+ }
+
+ // Find the closing '"' character.
+ for (; *r != '"'; ++r)
+ {
+ continue;
+ }
+
+ // Swap it for a '>'
+ if (*r == '"')
+ {
+ *r = '>';
+ }
+}
+
+void
+DRV_get_orb_idl_includes (void)
+{
+ static char const orb_idl[] = "tao/orb.idl";
+
+ // Search for orb.idl in supplied include file search paths.
+ char const * directory = 0;
+ FILE * fp = idl_global->open_included_file (orb_idl, directory);
+
+ if (fp == 0)
+ {
+ // Fall back on $TAO_ROOT/tao/orb.idl if orb.idl is not in the
+ // include path.
+ ACE_CString orb_idl_path (ACE_CString (idl_global->tao_root ())
+ + ACE_CString ('/')
+ + ACE_CString (orb_idl));
+
+ fp = ACE_OS::fopen (orb_idl_path.c_str (), "r");
+
+ if (fp == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "TAO_IDL: cannot open or find file: %s\n",
+ orb_idl_path.c_str ()));
+
+ throw Bailout ();
+ }
+ }
+ else
+ {
+ // Make sure the include directory containing orb.idl is passed
+ // to the preprocessor.
+ // This should go after user supplied include paths.
+ ACE_CString include_path_arg;
+ DRV_add_include_path (include_path_arg, directory, "/tao");
+ }
+
+ while (DRV_get_line (fp))
+ {
+ // Find the included .pidl files in orb.idl and add them to the
+ // included IDL file list.
+ DRV_check_for_include (drv_line);
+ }
+
+ ACE_OS::fclose (fp);
+}
+
+// Strip down a name to the last component,
+// i.e. everything after the last '/' or '\' character.
+static char *
+DRV_stripped_name (char *fn)
+{
+ char *n = fn;
+ size_t l;
+
+ if (n == 0)
+ {
+ return 0;
+ }
+
+ l = ACE_OS::strlen (n);
+ int slash_found = 0;
+
+ for (n += l - 1; n >= fn && !slash_found; n--)
+ {
+ slash_found = (*n == '/' || *n == '\\');
+ }
+
+ n += 1;
+
+ if (slash_found)
+ {
+ n += 1;
+ }
+
+ return n;
+}
+
+// Pass input through preprocessor.
+void
+DRV_pre_proc (const char *myfile)
+{
+ const char* tmpdir = idl_global->temp_dir ();
+ static const char temp_file_extension[] = ".cpp";
+
+ static char const tao_idlf_template[] = "tao-idlf_XXXXXX";
+
+ size_t const tlen =
+ ACE_OS::strlen (tmpdir) + sizeof (temp_file_extension);
+
+ // Prevent a buffer overrun.
+ if (tlen + sizeof (tao_idlf_template) > sizeof (tmp_file))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: temporary path/filename length is greater than "
+ "length allowed by platform\n",
+ idl_global->prog_name ()));
+
+
+ throw Bailout ();
+ }
+
+ ACE_OS::strcpy (tmp_file, tmpdir);
+
+// Append temporary filename template to temporary directory.
+ ACE_OS::strcat (tmp_file, tao_idlf_template);
+
+ ACE_HANDLE const tf_fd = ACE_OS::mkstemp (tmp_file);
+
+ if (tf_fd == ACE_INVALID_HANDLE)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: Unable to create temporary file: %m\n",
+ idl_global->prog_name ()));
+
+
+ throw Bailout ();
+ }
+
+ char tmp_cpp_file [MAXPATHLEN + 1] = { 0 };
+
+ // Append C++ source file extension. Temporary files will be renamed
+ // to these filenames.
+ ACE_OS::strcpy (tmp_cpp_file, tmp_file);
+ ACE_OS::strcat (tmp_cpp_file, temp_file_extension);
+
+ char * const t_file = tmp_cpp_file;
+
+ ACE_OS::close (tf_fd);
+
+
+#if defined (ACE_OPENVMS)
+ {
+ char main_abspath[MAXPATHLEN] = "";
+ char trans_path[MAXPATHLEN] = "";
+ char *main_fullpath =
+ ACE_OS::realpath (IDL_GlobalData::translateName (myfile, trans_path),
+ main_abspath);
+ idl_global->set_main_filename (
+ idl_global->utl_string_factory (main_fullpath));
+ }
+#else
+ idl_global->set_main_filename (idl_global->utl_string_factory (myfile));
+#endif
+
+ ACE_Auto_String_Free safety (ACE_OS::strdup (myfile));
+ UTL_String *tmp =
+ idl_global->utl_string_factory (DRV_stripped_name (safety.get ()));
+ idl_global->set_stripped_filename (tmp);
+
+ idl_global->set_real_filename (idl_global->utl_string_factory (myfile)); //t_ifile));
+
+ DRV_cpp_expand_output_arg (t_file);
+ DRV_cpp_putarg (myfile);
+
+ // Rename temporary files so that they have extensions accepted
+ // by the preprocessor. Renaming is (supposed to be) an atomic
+ // operation so we shouldn't be susceptible to attack.
+if (ACE_OS::rename (tmp_file, t_file) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: Unable to rename temporary file: %m\n",
+ idl_global->prog_name ()));
+
+
+ throw Bailout ();
+ }
+
+ // Remove any existing output file.
+(void) ACE_OS::unlink (t_file);
+
+ ACE_HANDLE fd = ACE_INVALID_HANDLE;
+
+ if (output_arg_format == 0)
+ {
+ // If the following open() fails, then we're either being hit with a
+ // symbolic link attack, or another process opened the file before
+ // us.
+#if defined (ACE_OPENVMS)
+ //FUZZ: disable check_for_lack_ACE_OS
+ fd = ::open (t_file, O_WRONLY | O_CREAT | O_EXCL,
+ ACE_DEFAULT_FILE_PERMS,
+ "shr=get,put,upd", "ctx=rec", "fop=dfw");
+ //FUZZ: enable check_for_lack_ACE_OS
+#else
+ fd = ACE_OS::open (t_file,
+ O_WRONLY | O_CREAT | O_EXCL,
+ ACE_DEFAULT_FILE_PERMS);
+#endif
+
+ if (fd == ACE_INVALID_HANDLE)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: cannot open temp file \"%s\" for writing\n",
+ idl_global->prog_name (),
+ t_file));
+
+
+ throw Bailout ();
+ }
+ }
+
+ char * tmp_arglist [DRV_MAX_ARGCOUNT] = { 0 };
+
+ for (size_t i = 0; i < DRV_argcount; ++i)
+ {
+ tmp_arglist[i] = ACE::strnew (DRV_arglist[i]);
+ }
+
+ if (mcpp_lib_main (DRV_argcount, tmp_arglist) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: mcpp preprocessor execution failed\n",
+ idl_global->prog_name ()));
+ throw Bailout ();
+ }
+
+ for (size_t i = 0; i < DRV_argcount; ++i)
+ delete tmp_arglist[i];
+
+
+ // Remove the null termination and the input file from the DRV_arglist,
+ // the next file will the previous args.
+ ACE::strdelete (const_cast<char *> (DRV_arglist[DRV_argcount - 2]));
+
+ DRV_argcount -= 2;
+
+ FILE * const yyin = ACE_OS::fopen (t_file, "r");
+
+ if (yyin == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: Could not open cpp output file: %p\n",
+ idl_global->prog_name (),
+ t_file));
+
+ throw Bailout ();
+ }
+
+ FE_set_yyin (yyin);
+
+ if (idl_global->compile_flags () & IDL_CF_ONLY_PREPROC)
+ {
+ FILE *preproc = ACE_OS::fopen (t_file, "r");
+ char buffer[ACE_MAXLOGMSGLEN];
+ size_t bytes;
+
+ if (preproc == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: Could not open cpp output file: %p\n",
+ idl_global->prog_name (),
+ t_file));
+
+ throw Bailout ();
+ }
+
+ // ACE_DEBUG sends to stderr - we want stdout for this dump
+ // of the preprocessor output. So we modify the singleton that
+ // was created in this process. Since IDL_CF_ONLY_PREPROC causes
+ // an (almost) immediate exit below, we don't have to restore
+ // the singleton's default parameters.
+ ACE_Log_Msg *out = ACE_Log_Msg::instance ();
+ out->msg_ostream (&cout);
+ out->clr_flags (ACE_Log_Msg::STDERR);
+ out->set_flags (ACE_Log_Msg::OSTREAM);
+
+ while ((bytes = ACE_OS::fread (buffer,
+ sizeof (char),
+ ACE_MAXLOGMSGLEN - 1,
+ preproc))
+ != 0)
+ {
+ buffer[bytes] = 0;
+
+ ACE_DEBUG ((LM_DEBUG,
+ buffer));
+ }
+
+ ACE_OS::fclose (preproc);
+ }
+
+ if (ACE_OS::unlink (t_file) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: Could not remove cpp output file: %p\n",
+ idl_global->prog_name (),
+ t_file));
+
+ throw Bailout ();
+ }
+}
diff --git a/TAO/TAO_IDL/preproc.mpb b/TAO/TAO_IDL/preproc.mpb
new file mode 100644
index 00000000000..f3b4a0d1dac
--- /dev/null
+++ b/TAO/TAO_IDL/preproc.mpb
@@ -0,0 +1,11 @@
+feature(mcpp) {
+ Source_Files {
+ driver/drv_mcpp_preproc.cpp
+ }
+}
+
+feature(!mcpp) {
+ Source_Files {
+ driver/drv_preproc.cpp
+ }
+} \ No newline at end of file
diff --git a/TAO/TAO_IDL/tao_idl.cpp b/TAO/TAO_IDL/tao_idl.cpp
index 8106ce99f70..b696734dbb8 100644
--- a/TAO/TAO_IDL/tao_idl.cpp
+++ b/TAO/TAO_IDL/tao_idl.cpp
@@ -309,7 +309,7 @@ DRV_drive (const char *s)
*/
int
-main (int argc, char *argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
try
{
diff --git a/TAO/TAO_IDL/tao_idl.mpc b/TAO/TAO_IDL/tao_idl.mpc
index ad32450cd3c..0d7d5618a39 100644
--- a/TAO/TAO_IDL/tao_idl.mpc
+++ b/TAO/TAO_IDL/tao_idl.mpc
@@ -1,7 +1,7 @@
// -*- MPC -*-
// $Id$
-project(TAO_IDL_EXE) : aceexe, install, tao_output, crosscompile {
+project(TAO_IDL_EXE) : aceexe, install, tao_output, crosscompile, mcpp, preproc {
exename = tao_idl
libs += TAO_IDL_BE TAO_IDL_FE
install = $(ACE_ROOT)/bin
@@ -36,7 +36,6 @@ project(TAO_IDL_EXE) : aceexe, install, tao_output, crosscompile {
Source_Files {
driver/drv_args.cpp
- driver/drv_preproc.cpp
tao_idl.cpp
}
diff --git a/TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp b/TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp
index 64dbeb96fc7..3675d0fdaf5 100644
--- a/TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp
+++ b/TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp
@@ -27,7 +27,7 @@
#include "ace/Log_Msg.h"
int
-main (int, char*[])
+ACE_TMAIN(int, ACE_TCHAR *[])
{
ACE_ERROR ((LM_INFO,
"This program is only supported "
diff --git a/TAO/orbsvcs/Notify_Service/NT_Notify_Server.cpp b/TAO/orbsvcs/Notify_Service/NT_Notify_Server.cpp
index 90ce225d6e1..48ae3e772fe 100644
--- a/TAO/orbsvcs/Notify_Service/NT_Notify_Server.cpp
+++ b/TAO/orbsvcs/Notify_Service/NT_Notify_Server.cpp
@@ -28,7 +28,7 @@
#include "ace/Log_Msg.h"
int
-main (int, char*[])
+ACE_TMAIN(int, ACE_TCHAR *[])
{
ACE_ERROR ((LM_INFO,
"This program is only supported "
diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Consumer.cpp b/TAO/orbsvcs/examples/CosEC/Simple/Consumer.cpp
index 1a600a91e0f..3ec1581f3de 100644
--- a/TAO/orbsvcs/examples/CosEC/Simple/Consumer.cpp
+++ b/TAO/orbsvcs/examples/CosEC/Simple/Consumer.cpp
@@ -8,7 +8,7 @@ ACE_RCSID (CosEC_Examples,
"$Id$")
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
Consumer consumer;
diff --git a/TAO/orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc b/TAO/orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc
index 7a91454ad07..9537776ef03 100644
--- a/TAO/orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc
+++ b/TAO/orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc
@@ -2,18 +2,27 @@
// $Id$
project(*Service) : orbsvcsexe, event, event_serv, naming {
+
+ exename = Service
+
Source_Files {
Service.cpp
}
}
project(*Consumer) : orbsvcsexe, event, event_skel {
+
+ exename = Consumer
+
Source_Files {
Consumer.cpp
}
}
project(*Supplier) : orbsvcsexe, event, event_skel {
+
+ exename = Supplier
+
Source_Files {
Supplier.cpp
}
diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Service.cpp b/TAO/orbsvcs/examples/CosEC/Simple/Service.cpp
index 7217f16ee8a..d15a2af735a 100644
--- a/TAO/orbsvcs/examples/CosEC/Simple/Service.cpp
+++ b/TAO/orbsvcs/examples/CosEC/Simple/Service.cpp
@@ -14,7 +14,7 @@ const char *ior_output_file = "ec.ior";
int parse_args (int argc, char *argv[]);
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
TAO_CEC_Default_Factory::init_svcs ();
diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Supplier.cpp b/TAO/orbsvcs/examples/CosEC/Simple/Supplier.cpp
index 03a0c13e02a..c39ad862e31 100644
--- a/TAO/orbsvcs/examples/CosEC/Simple/Supplier.cpp
+++ b/TAO/orbsvcs/examples/CosEC/Simple/Supplier.cpp
@@ -9,7 +9,7 @@ ACE_RCSID (CosEC_Examples,
"$Id$")
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
Supplier supplier;
diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp b/TAO/orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp
index f11dc27dbee..545183495d2 100644
--- a/TAO/orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp
+++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp
@@ -10,7 +10,7 @@ ACE_RCSID (CosEC_Examples,
"$Id$")
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
try
diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc b/TAO/orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc
index cddcd128801..22056c72cb8 100644
--- a/TAO/orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc
+++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc
@@ -2,6 +2,8 @@
// $Id$
project(*Consumer) : event_skel, orbsvcsexe, portableserver, naming {
+ exename = Consumer
+
requires += ec_typed_events
source_files {
Consumer.cpp
@@ -10,6 +12,8 @@ project(*Consumer) : event_skel, orbsvcsexe, portableserver, naming {
}
project(*Supplier) : event_skel, orbsvcsexe, portableserver, naming {
+ exename = Supplier
+
requires += ec_typed_events
after += CosEC_TypedSimple_Consumer
idl_files {
diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp b/TAO/orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp
index a51632e9a07..98f7088d0cc 100644
--- a/TAO/orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp
+++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp
@@ -7,7 +7,7 @@
ACE_RCSID(CosEC_Examples, Supplier, "$Id:")
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
try
diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc b/TAO/orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc
index 482fcc7a42e..eecde8c04b7 100644
--- a/TAO/orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc
+++ b/TAO/orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc
@@ -32,6 +32,7 @@ project(*Controller) : orbsvcsexe {
// A client that uses corba to test out basic imr functionality
project(*Test) : orbsvcsexe {
+ exename = test
after += *IDL
source_files {
test.cpp
@@ -43,6 +44,7 @@ project(*Test) : orbsvcsexe {
// A server to use with the imr
project(*TestServer) : orbsvcsexe, portableserver, iortable, avoids_corba_e_micro {
+ exename = test_server
after += *IDL
// The gnuace specific portion is to prevent invalid object files from
// IDL generated files being compiled simultaneously with parallel builds.
diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/test.cpp b/TAO/orbsvcs/examples/ImR/Combined_Service/test.cpp
index b74936e8804..feb64b55592 100644
--- a/TAO/orbsvcs/examples/ImR/Combined_Service/test.cpp
+++ b/TAO/orbsvcs/examples/ImR/Combined_Service/test.cpp
@@ -20,7 +20,7 @@
using namespace CORBA;
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
try
{
diff --git a/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.cpp b/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.cpp
index f5ba3f77ca2..c7ceb01cafc 100644
--- a/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.cpp
+++ b/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.cpp
@@ -74,7 +74,7 @@ public:
if (ACE_OS::thr_create (&tracker_thunk,
this,
THR_JOINABLE,
- &thread_) != 0)
+ &thread_) != 0)
ACE_OS::abort ();
}
@@ -198,7 +198,7 @@ private:
};
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
try
{
diff --git a/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp
index 498ce553efd..343da42b2ad 100644
--- a/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp
+++ b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp
@@ -33,7 +33,7 @@ using namespace CosNotification;
using namespace CosNotifyChannelAdmin;
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
try
{
diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp
index 9c2c1d2ffef..972181383dc 100644
--- a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp
+++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp
@@ -18,7 +18,7 @@ const RtecEventComm::EventType MY_EVENT_TYPE = ACE_ES_EVENT_UNDEFINED + 1;
static const char* ecname = 0;
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
Consumer consumer;
diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.cpp b/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.cpp
index 2831f1b3a23..6f3009c2350 100644
--- a/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.cpp
+++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.cpp
@@ -16,7 +16,7 @@ ACE_RCSID (EC_Examples,
static const char* ecname = 0;
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
EC channel;
diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp
index 8a6e88ed107..abda8735f78 100644
--- a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp
+++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp
@@ -17,7 +17,7 @@ static const char* supplierec = 0;
static const char* consumerec = 0;
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
Gateway gateway;
diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc b/TAO/orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc
index 2ece2c2a38d..2671b2a5ed7 100644
--- a/TAO/orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc
+++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc
@@ -2,6 +2,9 @@
// $Id$
project(*Consumer): messaging, rteventexe, naming {
+
+ exename = Consumer
+
requires += corba_messaging
Source_Files {
@@ -10,6 +13,9 @@ project(*Consumer): messaging, rteventexe, naming {
}
project(*Supplier): messaging, rteventexe, naming {
+
+ exename = Supplier
+
requires += corba_messaging
Source_Files {
@@ -18,6 +24,9 @@ project(*Supplier): messaging, rteventexe, naming {
}
project(*): messaging, rteventexe, rtevent_serv, naming {
+
+ exename = Gateway
+
requires += corba_messaging
Source_Files {
@@ -26,6 +35,9 @@ project(*): messaging, rteventexe, rtevent_serv, naming {
}
project(*EC): messaging, rteventexe, rtevent_serv, naming {
+
+ exename = EC
+
requires += corba_messaging
Source_Files {
diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp
index f016dbfff30..9e2cf6558cd 100644
--- a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp
+++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp
@@ -19,7 +19,7 @@ const RtecEventComm::EventType MY_EVENT_TYPE = ACE_ES_EVENT_UNDEFINED + 1;
static const char* ecname = 0;
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
Supplier supplier;
diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc b/TAO/orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc
index 88d36ead38f..79b652f0621 100644
--- a/TAO/orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc
+++ b/TAO/orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc
@@ -1,3 +1,4 @@
// $Id$
project: orbsvcsexe, rtkokyuevent, rtevent_serv {
+ exename = Service
}
diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/Service.cpp b/TAO/orbsvcs/examples/RtEC/Kokyu/Service.cpp
index cd73298bbde..9654858f777 100644
--- a/TAO/orbsvcs/examples/RtEC/Kokyu/Service.cpp
+++ b/TAO/orbsvcs/examples/RtEC/Kokyu/Service.cpp
@@ -42,10 +42,10 @@ typedef TAO_Reconfig_Scheduler<TAO_RMS_FAIR_Reconfig_Sched_Strategy, TAO_SYNCH_M
typedef TAO_Reconfig_Scheduler<TAO_MUF_FAIR_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX> RECONFIG_MUF_SCHED_TYPE;
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
ACE_UNUSED_ARG (config_run);
-
+
//TAO_EC_Default_Factory::init_svcs ();
TAO_EC_Kokyu_Factory::init_svcs ();
diff --git a/TAO/orbsvcs/examples/RtEC/MCast/MCast.cpp b/TAO/orbsvcs/examples/RtEC/MCast/MCast.cpp
index 6f7fc2bebab..af1e33adb86 100644
--- a/TAO/orbsvcs/examples/RtEC/MCast/MCast.cpp
+++ b/TAO/orbsvcs/examples/RtEC/MCast/MCast.cpp
@@ -25,7 +25,7 @@ const char *udp_mcast_address =
int parse_args (int argc, char *argv[]);
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
// Register the default factory in the Service Configurator.
// If your platform supports static constructors then you can
diff --git a/TAO/orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc b/TAO/orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc
index ebe69a8ddbc..ec419f3bb13 100644
--- a/TAO/orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc
+++ b/TAO/orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc
@@ -2,4 +2,5 @@
// $Id$
project : orbsvcsexe, rtevent_serv, rtsched {
+ exename = MCast
}
diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc b/TAO/orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc
index ebe69a8ddbc..f28dd9330a4 100644
--- a/TAO/orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc
+++ b/TAO/orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc
@@ -2,4 +2,5 @@
// $Id$
project : orbsvcsexe, rtevent_serv, rtsched {
+ exename = Service
}
diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/Service.cpp b/TAO/orbsvcs/examples/RtEC/Schedule/Service.cpp
index 6b788914137..961d7db4a12 100644
--- a/TAO/orbsvcs/examples/RtEC/Schedule/Service.cpp
+++ b/TAO/orbsvcs/examples/RtEC/Schedule/Service.cpp
@@ -25,7 +25,7 @@ int parse_args (int argc, char *argv[]);
typedef TAO_Reconfig_Scheduler<TAO_MUF_FAIR_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX> RECONFIG_SCHED_TYPE;
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
TAO_EC_Default_Factory::init_svcs ();
diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Consumer.cpp b/TAO/orbsvcs/examples/RtEC/Simple/Consumer.cpp
index 5203f82a466..1e554a81916 100644
--- a/TAO/orbsvcs/examples/RtEC/Simple/Consumer.cpp
+++ b/TAO/orbsvcs/examples/RtEC/Simple/Consumer.cpp
@@ -10,7 +10,7 @@ ACE_RCSID (EC_Examples,
"$Id$")
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
Consumer consumer;
diff --git a/TAO/orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc b/TAO/orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc
index b98ff0f88e4..0982c19dbc0 100644
--- a/TAO/orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc
+++ b/TAO/orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc
@@ -2,18 +2,27 @@
// $Id$
project(*Service) : orbsvcsexe, rtevent_serv, naming {
+
+ exename = Service
+
source_files {
Service.cpp
}
}
project(*Supplier) : orbsvcsexe, rtevent_skel, naming {
+
+ exename = Supplier
+
source_files {
Supplier.cpp
}
}
project(*Consumer) : orbsvcsexe, rtevent_skel, naming {
+
+ exename = Consumer
+
source_files {
Consumer.cpp
}
diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Service.cpp b/TAO/orbsvcs/examples/RtEC/Simple/Service.cpp
index 997078045e7..291313352b7 100644
--- a/TAO/orbsvcs/examples/RtEC/Simple/Service.cpp
+++ b/TAO/orbsvcs/examples/RtEC/Simple/Service.cpp
@@ -15,7 +15,7 @@ const char *ior_output_file = "ec.ior";
int parse_args (int argc, char *argv[]);
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
TAO_EC_Default_Factory::init_svcs ();
diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Supplier.cpp b/TAO/orbsvcs/examples/RtEC/Simple/Supplier.cpp
index 56b0a8063cc..4e26cbf4ba7 100644
--- a/TAO/orbsvcs/examples/RtEC/Simple/Supplier.cpp
+++ b/TAO/orbsvcs/examples/RtEC/Simple/Supplier.cpp
@@ -11,7 +11,7 @@ ACE_RCSID (EC_Examples,
"$Id$")
int
-main (int argc, char* argv[])
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
Supplier supplier;
diff --git a/TAO/orbsvcs/orbsvcs/IFRService/ConstantDef_i.h b/TAO/orbsvcs/orbsvcs/IFRService/ConstantDef_i.h
index 20c9f955f0e..a0acdfd7b89 100644
--- a/TAO/orbsvcs/orbsvcs/IFRService/ConstantDef_i.h
+++ b/TAO/orbsvcs/orbsvcs/IFRService/ConstantDef_i.h
@@ -14,7 +14,6 @@
*/
//=============================================================================
-
#ifndef TAO_CONSTANTDEF_I_H
#define TAO_CONSTANTDEF_I_H
@@ -49,50 +48,33 @@ public:
virtual ~TAO_ConstantDef_i (void);
/// Return our definition kind.
- virtual CORBA::DefinitionKind def_kind ()
-;
+ virtual CORBA::DefinitionKind def_kind (void);
/// From Contained_i's pure virtual function.
- virtual CORBA::Contained::Description *describe ()
-;
+ virtual CORBA::Contained::Description *describe (void);
/// From Contained_i's pure virtual function.
- virtual CORBA::Contained::Description *describe_i ()
-;
+ virtual CORBA::Contained::Description *describe_i (void);
- virtual CORBA::TypeCode_ptr type ()
-;
+ virtual CORBA::TypeCode_ptr type (void);
- CORBA::TypeCode_ptr type_i ()
-;
+ CORBA::TypeCode_ptr type_i (void);
- virtual CORBA::IDLType_ptr type_def ()
-;
+ virtual CORBA::IDLType_ptr type_def (void);
- CORBA::IDLType_ptr type_def_i ()
-;
+ CORBA::IDLType_ptr type_def_i (void);
- virtual void type_def (
- CORBA::IDLType_ptr type_def)
-;
+ virtual void type_def (CORBA::IDLType_ptr type_def);
- void type_def_i (
- CORBA::IDLType_ptr type_def)
-;
+ void type_def_i (CORBA::IDLType_ptr type_def);
- virtual CORBA::Any *value ()
-;
+ virtual CORBA::Any *value (void);
- CORBA::Any *value_i ()
-;
+ CORBA::Any *value_i (void);
- virtual void value (
- const CORBA::Any &value)
-;
+ virtual void value (const CORBA::Any &value);
- void value_i (
- const CORBA::Any &value)
-;
+ void value_i (const CORBA::Any &value);
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/IFRService/EnumDef_i.h b/TAO/orbsvcs/orbsvcs/IFRService/EnumDef_i.h
index 7f44a8e27e8..8d9ade9026a 100644
--- a/TAO/orbsvcs/orbsvcs/IFRService/EnumDef_i.h
+++ b/TAO/orbsvcs/orbsvcs/IFRService/EnumDef_i.h
@@ -43,36 +43,27 @@ public:
//
public:
/// Constructor
- TAO_EnumDef_i (TAO_Repository_i *repoy);
+ TAO_EnumDef_i (TAO_Repository_i *repo);
/// Destructor
virtual ~TAO_EnumDef_i (void);
/// Return our definition kind.
- virtual CORBA::DefinitionKind def_kind ()
-;
+ virtual CORBA::DefinitionKind def_kind (void);
/// From IDLType_i's pure virtual function.
- virtual CORBA::TypeCode_ptr type ()
-;
+ virtual CORBA::TypeCode_ptr type (void);
/// From IDLType_i's pure virtual function.
- virtual CORBA::TypeCode_ptr type_i ()
-;
+ virtual CORBA::TypeCode_ptr type_i (void);
- virtual CORBA::EnumMemberSeq *members ()
-;
+ virtual CORBA::EnumMemberSeq *members (void);
- CORBA::EnumMemberSeq *members_i ()
-;
+ CORBA::EnumMemberSeq *members_i (void);
- virtual void members (
- const CORBA::EnumMemberSeq &members)
-;
+ virtual void members (const CORBA::EnumMemberSeq &members);
- void members_i (
- const CORBA::EnumMemberSeq &members)
-;
+ void members_i (const CORBA::EnumMemberSeq &members);
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/IFRService/IFR_Service_Utils.cpp b/TAO/orbsvcs/orbsvcs/IFRService/IFR_Service_Utils.cpp
index c99ff51797f..5a3f08b3858 100644
--- a/TAO/orbsvcs/orbsvcs/IFRService/IFR_Service_Utils.cpp
+++ b/TAO/orbsvcs/orbsvcs/IFRService/IFR_Service_Utils.cpp
@@ -16,6 +16,7 @@
#include "tao/Profile.h"
#include "tao/AnyTypeCode/ValueModifierC.h"
#include "ace/Auto_Ptr.h"
+#include "ace/OS_NS_fcntl.h"
ACE_RCSID (IFR_Service,
IFR_Service,
@@ -330,7 +331,43 @@ TAO_IFR_Server::create_repository (void)
// Add the repository to the ORB's table of initialized object references.
this->orb_->register_initial_reference ("InterfaceRepository",
repo_ref);
+
+ const char *ior_filename = OPTIONS::instance ()->ior_output_file ();
+ ACE_HANDLE fd = ACE_OS::open (ior_filename,
+ O_RDWR | O_CREAT | O_TRUNC,
+ ACE_DEFAULT_FILE_PERMS);
+ if (fd == ACE_INVALID_HANDLE)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO_IFR_Server::create_repository - ",
+ "ACE_OS::open() failed\n"),
+ -1);
+ }
+
+ const char *ifr_ior = this->ifr_ior_.in ();
+ size_t ior_size = ACE_OS::strlen (ifr_ior) + 1;
+ ssize_t result = ACE_OS::write (fd, ifr_ior, ior_size);
+
+ if (result != ior_size)
+ {
+ ACE_OS::unlink (ior_filename);
+ ACE_OS::close (fd);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO_IFR_Server::create_repository - ",
+ "ACE_OS::write() failed\n"),
+ -1);
+ }
+
+ if (ACE_OS::close (fd) != 0)
+ {
+ ACE_OS::unlink (ior_filename);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO_IFR_Server::create_repository - ",
+ ACE_TEXT ("ACE_OS::close() failed\n")),
+ -1);
+ }
+/*
FILE *output_file_ =
ACE_OS::fopen (OPTIONS::instance()->ior_output_file (),
"w");
@@ -340,7 +377,7 @@ TAO_IFR_Server::create_repository (void)
this->ifr_ior_.in ());
ACE_OS::fclose (output_file_);
-
+*/
return 0;
}
diff --git a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp
index e3f86094dee..f263b2011c3 100644
--- a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp
+++ b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp
@@ -278,7 +278,7 @@ ACE_TMAIN(int argc, ACE_TCHAR *argv[])
#else
int
-main (int, char *[])
+ACE_TMAIN(int, ACE_TCHAR *[])
{
return 0;
}
diff --git a/TAO/orbsvcs/tests/Redundant_Naming/client.cpp b/TAO/orbsvcs/tests/Redundant_Naming/client.cpp
index e2bc46925d8..263084c4d5f 100644
--- a/TAO/orbsvcs/tests/Redundant_Naming/client.cpp
+++ b/TAO/orbsvcs/tests/Redundant_Naming/client.cpp
@@ -79,7 +79,7 @@ My_Test_Object::id (CORBA::Short id)
// This function runs the test.
int
-main (int argc, ACE_TCHAR **argv)
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
int c_breath = 4;
int c_depth = 4;
diff --git a/TAO/orbsvcs/tests/Sched/DynSched_Test.cpp b/TAO/orbsvcs/tests/Sched/DynSched_Test.cpp
index b711f653685..b0567d8321c 100644
--- a/TAO/orbsvcs/tests/Sched/DynSched_Test.cpp
+++ b/TAO/orbsvcs/tests/Sched/DynSched_Test.cpp
@@ -6,8 +6,8 @@
# include <quantify.h>
#endif /* ACE_HAS_QUANTIFY */
-ACE_RCSID (Sched,
- DynSched_Test,
+ACE_RCSID (Sched,
+ DynSched_Test,
"$Id$")
// period times, in 100 nanoseconds
@@ -258,7 +258,7 @@ DynSched_Test::run_schedule (ACE_Scheduler_Strategy &strategy,
}
int
-main (int, char *[])
+ACE_TMAIN(int, ACE_TCHAR *[])
{
int result = 0;
diff --git a/TAO/tao/GIOP_Message_Generator_Parser_12.cpp b/TAO/tao/GIOP_Message_Generator_Parser_12.cpp
index 871a8a24d50..35b750b5ea1 100644
--- a/TAO/tao/GIOP_Message_Generator_Parser_12.cpp
+++ b/TAO/tao/GIOP_Message_Generator_Parser_12.cpp
@@ -69,7 +69,7 @@ TAO_GIOP_Message_Generator_Parser_12::write_request_header (
msg.write_octet_array (reserved, 3);
- if (this->marshall_target_spec (spec, msg) == false)
+ if (!this->marshall_target_spec (spec, msg))
return false;
// Write the operation name
@@ -77,7 +77,8 @@ TAO_GIOP_Message_Generator_Parser_12::write_request_header (
opdetails.opname ());
// Write the service context list
- msg << opdetails.request_service_info ();
+ if (!(msg << opdetails.request_service_info ()))
+ return false;
// We align the pointer only if the operation has arguments.
if (opdetails.argument_flag ()
@@ -96,7 +97,8 @@ TAO_GIOP_Message_Generator_Parser_12::write_locate_request_header (
TAO_OutputCDR &msg)
{
// Write the request id
- msg << request_id;
+ if (!(msg << request_id))
+ return false;
// Write the target address
if (!(this->marshall_target_spec (spec, msg)))
@@ -269,10 +271,19 @@ TAO_GIOP_Message_Generator_Parser_12::parse_request_header (
// verify a digital signature, if that is required in this security
// environment. It may be required even when using IPSEC security
// infrastructure.
- IOP::ServiceContextList &req_service_info =
- request.request_service_info ();
+ IOP::ServiceContextList &req_service_info = request.request_service_info ();
- input >> req_service_info;
+ if (!(input >> req_service_info))
+ {
+ if (TAO_debug_level)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) parse_request_header, ")
+ ACE_TEXT ("extracting context\n")));
+ }
+
+ return -1;
+ }
// Check an process if BiDir contexts are available
if (request.orb_core ()->bidir_giop_policy ())
@@ -297,11 +308,9 @@ TAO_GIOP_Message_Generator_Parser_12::parse_locate_header (
// Get the stream .
TAO_InputCDR &msg = request.incoming_stream ();
- CORBA::Boolean hdr_status = true;
-
// Get the request id.
CORBA::ULong req_id = 0;
- hdr_status = msg.read_ulong (req_id);
+ CORBA::Boolean hdr_status = msg.read_ulong (req_id);
// Store it in the Locate request classes
request.request_id (req_id);
@@ -324,7 +333,7 @@ TAO_GIOP_Message_Generator_Parser_12::parse_reply (
if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr, params) == -1)
return -1;
- if ((cdr >> params.svc_ctx_) == 0)
+ if (!(cdr >> params.svc_ctx_))
{
if (TAO_debug_level)
{
@@ -351,7 +360,6 @@ TAO_GIOP_Message_Generator_Parser_12::parse_locate_reply (
TAO_Pluggable_Reply_Params &params)
{
if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr, params) == -1)
-
return -1;
// Note: We dont align the pointer to an 8 byte boundary for a
@@ -398,7 +406,8 @@ TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
case TAO_Target_Specification::Key_Addr:
{
// As this is a union send in the discriminant first
- msg << GIOP::KeyAddr;
+ if (!(msg << GIOP::KeyAddr))
+ return false;
// Get the object key
const TAO::ObjectKey *key = spec.object_key ();
@@ -406,7 +415,8 @@ TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
if (key)
{
// Marshall in the object key
- msg << *key;
+ if (!(msg << *key))
+ return false;
}
else
{
@@ -446,7 +456,8 @@ TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
case TAO_Target_Specification::Reference_Addr:
{
// As this is a union send in the discriminant first
- msg << GIOP::ReferenceAddr;
+ if (!(msg << GIOP::ReferenceAddr))
+ return false;
// Get the IOR
IOP::IOR *ior = 0;
@@ -457,8 +468,10 @@ TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
// This is a struct IORAddressingInfo. So, marshall each
// member of the struct one after another in the order
// defined.
- msg << index;
- msg << *ior;
+ if (!(msg << index))
+ return false;
+ if (!(msg << *ior))
+ return false;;
}
else
{
diff --git a/TAO/tao/Invocation_Base.cpp b/TAO/tao/Invocation_Base.cpp
index 48a0a6f557a..db035dfcf3e 100644
--- a/TAO/tao/Invocation_Base.cpp
+++ b/TAO/tao/Invocation_Base.cpp
@@ -143,7 +143,6 @@ namespace TAO
return TAO_INVOKE_SUCCESS;
}
-
Invocation_Status
Invocation_Base::receive_other_interception (void)
{
diff --git a/TAO/tao/LocalObject.h b/TAO/tao/LocalObject.h
index fa0a38e041d..a3521486020 100644
--- a/TAO/tao/LocalObject.h
+++ b/TAO/tao/LocalObject.h
@@ -217,8 +217,7 @@ private:
//@{
TAO_Local_RefCounted_Object (const TAO_Local_RefCounted_Object &);
TAO_Local_RefCounted_Object & operator = (
- const TAO_Local_RefCounted_Object &
- );
+ const TAO_Local_RefCounted_Object &);
//@}
};
diff --git a/TAO/tao/TAO_Server_Request.cpp b/TAO/tao/TAO_Server_Request.cpp
index 371d52005b6..eaee1862bc0 100644
--- a/TAO/tao/TAO_Server_Request.cpp
+++ b/TAO/tao/TAO_Server_Request.cpp
@@ -208,14 +208,14 @@ TAO_Service_Context &
TAO_ServerRequest::reply_service_context (void)
{
if (!operation_details_)
- {
- return this->reply_service_context_;
- }
+ {
+ return this->reply_service_context_;
+ }
else
- {
- return const_cast <TAO_Operation_Details*> (
- this->operation_details_)->reply_service_context ();
- }
+ {
+ return const_cast <TAO_Operation_Details*> (
+ this->operation_details_)->reply_service_context ();
+ }
}