summaryrefslogtreecommitdiff
path: root/ACE/TAO/TAO_IDL/contrib/mcpp/system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/TAO_IDL/contrib/mcpp/system.cpp')
-rw-r--r--ACE/TAO/TAO_IDL/contrib/mcpp/system.cpp4930
1 files changed, 4930 insertions, 0 deletions
diff --git a/ACE/TAO/TAO_IDL/contrib/mcpp/system.cpp b/ACE/TAO/TAO_IDL/contrib/mcpp/system.cpp
new file mode 100644
index 00000000000..ff8ef927b17
--- /dev/null
+++ b/ACE/TAO/TAO_IDL/contrib/mcpp/system.cpp
@@ -0,0 +1,4930 @@
+/*- $Id$
+ * Copyright (c) 1998, 2002-2008 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 O.S., compiler or compiler-driver.
+ * To port MCPP for the systems not yet ported, 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"
+#endif
+
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_sys_stat.h"
+
+#if HOST_SYS_FAMILY == SYS_UNIX
+#include "ace/OS_NS_unistd.h" /* For getcwd(), readlink() */
+#elif HOST_COMPILER == MSC || HOST_COMPILER == LCC
+#include "direct.h"
+#define getcwd( buf, size) _getcwd( buf, size)
+#elif HOST_COMPILER == BORLANDC
+#include "dir.h"
+#endif
+
+#include "sys/types.h"
+#include "sys/stat.h" /* For stat() */
+#if ! defined( S_ISREG)
+#define S_ISREG( mode) (mode & S_IFREG)
+#define S_ISDIR( mode) (mode & S_IFDIR)
+#endif
+#if HOST_COMPILER == MSC
+#define S_IFREG _S_IFREG
+#define S_IFDIR _S_IFDIR
+#define stat( path, stbuf) _stat( path, stbuf)
+#endif
+
+/* Function to compare path-list */
+#if FNAME_FOLD
+#if HOST_COMPILER == GNUC /* CYGWIN, MINGW, MAC */
+#include <ace/OS_NS_strings.h> /* POSIX 1, 2001 */
+#define str_case_eq( str1, str2) (ACE_OS::strcasecmp( str1, str2) == 0)
+#else /* MSC, BORLANDC, LCC */
+#if HOST_COMPILER == MSC
+#define stricmp( str1, str2) _stricmp( str1, str2)
+#endif
+#define str_case_eq( str1, str2) (ACE_OS::stricmp( str1, str2) == 0)
+#endif
+#else /* ! FNAME_FOLD */
+#define str_case_eq( str1, str2) (ACE_OS::strcmp( str1, str2) == 0)
+#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 /* Any other path-delimiter, define PATH_DELIM by yourself */
+#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 || HOST_COMPILER == GNUC
+#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 * mcpp_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, int trad);
+/* Check consistency of options */
+#if COMPILER != GNUC
+static void init_cpu_macro( int gval, int sse);
+/* Predefine CPU-dependent macros */
+#endif
+static void init_predefines( void);
+/* 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 void put_info( FILEINFO * sharp_file);
+/* Print compiler-specific-inf */
+static char * set_files( int argc, char ** argv, const char ** in_pp
+ , const 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_dir( const char * dirname, int framework);
+/* Normalize include directory path */
+static char * norm_path( const char * dir, const char * fname, int inf
+ , int hmap); /* Normalize pathname to compare */
+#if SYS_FAMILY == SYS_UNIX
+static void deref_syml( char * slbuf1, char * slbuf2, char * chk_start);
+/* Dereference symbolic linked directory and file */
+#endif
+#if COMPILER == GNUC
+static void init_gcc_macro( void);
+/* Predefine GCC-specific macros */
+static void chk_env( void);
+/* Check the environment variables */
+#elif COMPILER == MSC
+static void init_msc_macro( void);
+/* Predefine Visual C-specific macros */
+#endif
+static void def_macros( void);
+/* Define macros specified by -D */
+static void undef_macros( void);
+/* Undefine macros specified by -U */
+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 is_full_path( const char * path);
+/* The path is absolute path list ? */
+static int search_dir( char * filename, int searchlocal, int next);
+/* Search the include directories */
+static int open_file( const char ** dirp, const char * src_dir
+ , const char * filename, int local, int include_opt, int sys_frame);
+/* Open a source file */
+static const char * set_fname( const char * filename);
+/* Remember the source filename */
+#if SYSTEM == SYS_MAC
+#if COMPILER == GNUC
+static char * search_header_map( const char * hmap_file
+ , const char * filename, char * pathlist);
+/* Search header map file for a header */
+static unsigned hmap_hash( const char * fname);
+/* Get hash value for the fname */
+#endif
+static void init_framework( void);
+/* Initialize framework[] */
+static int search_framework( char * filename);
+/* Search "Framework" directories */
+static int search_subdir( char * fullname, char * cp, char * frame
+ , char * fname, int sys_frame);
+/* Search "Headers" and other dirs */
+#endif /* SYSTEM == SYS_MAC */
+#if 0 /* This function is only for debugging use */
+static int chk_dirp( const char ** dirp);
+/* Check validity of dirp arg for open_file() */
+#endif
+static void cur_file( FILEINFO * file, FILEINFO * sharp_file, int marker);
+/* Output current source file name */
+#if SYS_FAMILY == SYS_WIN
+static char * bsl2sl( char * filename);
+/* Convert \ to / in path-list */
+#endif
+static int is_junk( void);
+/* The directive has trailing junk? */
+static void do_once( const char * fullname);
+/* Process #pragma once */
+static int included( const char * fullname);
+/* 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 */
+static int mcpp_getopt( int argc, char * const * argv, const char * opts);
+/* getopt() to prevent linking of glibc getopt */
+
+/* for mcpp_getopt() */
+static int mcpp_optind = 1;
+static int mcpp_opterr = 1;
+static int mcpp_optopt;
+static char * mcpp_optarg;
+
+static int mb_changed = FALSE; /* Flag of -e option */
+static char cur_work_dir[ PATHMAX + 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; /* Include directories */
+static const char ** incend; /* -> active end of incdir */
+static int max_inc; /* Number of incdir[] */
+
+typedef struct inc_list { /* List of directories or files */
+ char * name; /* Filename or directory-name */
+ size_t len; /* Length of 'name' */
+} INC_LIST;
+
+/*
+ * fnamelist[] stores the souce file names opened by #include directive for
+ * debugging information.
+ */
+static INC_LIST * fnamelist; /* Source file names */
+static INC_LIST * fname_end; /* -> active end of fnamelist */
+static int max_fnamelist; /* Number of fnamelist[] */
+
+/* once_list[] stores the #pragma once file names. */
+static INC_LIST * once_list; /* Once opened file */
+static INC_LIST * once_end; /* -> active end of once_list */
+static int max_once; /* Number of once_list[] */
+
+#define INIT_NUM_INCLUDE 32 /* Initial number of incdir[] */
+#define INIT_NUM_FNAMELIST 256 /* Initial number of fnamelist[] */
+#define INIT_NUM_ONCE 64 /* Initial number of once_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 nflag = FALSE; /* Flag of -N (-undef) option */
+static long std_val = -1L; /* Value of __STDC_VERSION__ or __cplusplus */
+
+#define MAX_DEF 256
+#define MAX_UNDEF (MAX_DEF/4)
+static char * def_list[ MAX_DEF]; /* Macros to be defined */
+static const char * undef_list[ MAX_UNDEF]; /* Macros to be undefined */
+static size_t def_cnt(0); /* Count of def_list */
+static size_t undef_cnt (0); /* Count of undef_list */
+
+/* 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() */
+static int ansi; /* __STRICT_ANSI__ flag for GNUC */
+static int compat_mode;
+/* "Compatible" mode of recursive macro expansion */
+#define MAX_ARCH_LEN 16
+static char arch[ MAX_ARCH_LEN]; /* -arch or -m64, -m32 options */
+
+#if COMPILER == GNUC
+#define N_QUOTE_DIR 8
+/* quote_dir[]: Include directories for "header" specified by -iquote */
+/* quote_dir_end: Active end of quote_dir */
+static const char * quote_dir[ N_QUOTE_DIR];
+static const char ** quote_dir_end = quote_dir;
+/* sys_dirp indicates the first directory to search for system headers. */
+static const char ** sys_dirp = NULL; /* System header directory */
+static const char * sysroot = NULL; /* Logical root directory of header */
+static int i_split = FALSE; /* For -I- option */
+static int gcc_work_dir = FALSE; /* For -fworking-directory */
+static int gcc_maj_ver; /* __GNUC__ */
+static int gcc_min_ver; /* __GNUC_MINOR__ */
+static int dDflag = FALSE; /* Flag of -dD option */
+static int dMflag = FALSE; /* Flag of -dM 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 */
+#endif
+
+#if COMPILER == MSC
+static int wchar_t_modified = FALSE; /* -Zc:wchar_t flag */
+#endif
+
+#if COMPILER == LCC
+static const char * optim_name = "__LCCOPTIMLEVEL";
+#endif
+
+#if SYSTEM == SYS_CYGWIN
+static int no_cygwin = FALSE; /* -mno-cygwin */
+
+#elif SYSTEM == SYS_MAC
+#define MAX_FRAMEWORK 8
+static char * framework[ MAX_FRAMEWORK]; /* Framework directories*/
+static int num_framework; /* Current number of framework[] */
+static int sys_framework; /* System framework dir */
+static const char ** to_search_framework;
+/* Search framework[] next to the directory */
+static int in_import; /* #import rather than #include */
+#endif
+
+#define NO_DIR FALSE
+#if NO_DIR
+/* Unofficial feature to strip directory part of include file */
+static int no_dir;
+#endif
+
+#ifdef MCPP_LIB
+void init_system( void)
+/* Initialize static variables */
+{
+ if (sharp_filename)
+ ACE_OS::free( sharp_filename);
+ sharp_filename = 0;
+ incend = incdir = 0;
+ fnamelist = once_list = 0;
+ search_rule = SEARCH_INIT;
+ mb_changed = nflag = ansi = compat_mode = FALSE;
+ mkdep_fp = 0;
+ mkdep_target = mkdep_mf = mkdep_md = mkdep_mq = mkdep_mt = 0;
+ std_val = -1L;
+ def_cnt = undef_cnt = 0;
+ mcpp_optind = mcpp_opterr = 1;
+#if COMPILER == GNUC
+ sys_dirp = 0;
+ sysroot = 0;
+ gcc_work_dir = i_split = FALSE;
+ quote_dir_end = quote_dir;
+ dDflag = dMflag = FALSE;
+#endif
+#if COMPILER == MSC
+ wchar_t_modified = FALSE;
+#endif
+#if COMPILER == GNUC || COMPILER == MSC
+ preinc_end = preinclude;
+#endif
+#if SYSTEM == SYS_CYGWIN
+ no_cygwin = FALSE;
+#elif SYSTEM == SYS_MAC
+ num_framework = sys_framework = 0;
+ to_search_framework = 0;
+#endif
+#if NO_DIR
+ no_dir = FALSE;
+#endif
+}
+
+#endif
+
+#define OPTLISTLEN 80
+
+void do_options(
+ int argc,
+ char ** argv,
+ const char ** in_pp, /* Input file name */
+ const char ** out_pp /* Output file name */
+ )
+/*
+ * Process command line arguments, called only at MCPP startup.
+ */
+{
+ char optlist[ OPTLISTLEN]; /* List of option letter*/
+ const char * warning = "warning: -%c%s option is ignored\n";
+ int opt;
+ 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*/;
+ VAL_SIGN * valp;
+ int sflag; /* -S option or similar */
+ int trad; /* -traditional */
+ int old_mode; /* backup of 'mcpp_mode'*/
+ int gval, sse;
+ char * cp;
+ int i;
+#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 */
+#elif COMPILER == LCC
+ const char * debug_name = "__LCCDEBUGLEVEL";
+#endif
+
+ argv0 = argv[ 0];
+ nflag = unset_sys_dirs = show_path = sflag = trad = FALSE;
+ arch[ 0] = 0;
+ gval = sse = 0;
+ set_cplus_dir = TRUE;
+
+ /* Get current directory for -I option and #pragma once */
+ ACE_OS::getcwd( cur_work_dir, PATHMAX);
+#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__"); /* Already defined by init_defines() */
+ gcc_maj_ver = atoi( defp->repl);
+ defp = look_id( "__GNUC_MINOR__");
+ gcc_min_ver = atoi( defp->repl);
+ integrated_cpp = ((gcc_maj_ver == 3 && gcc_min_ver >= 3)
+ || gcc_maj_ver == 4);
+#endif
+#if COMPILER == GNUC || COMPILER == MSC
+ option_flags.dollar_in_name = TRUE;
+ /* GCC and Visual C allows '$' in name by default */
+#endif
+
+ set_opt_list( optlist);
+
+ opt_search: ;
+ while (mcpp_optind < argc
+ && (opt = mcpp_getopt( argc, argv, optlist)) != EOF) {
+
+ switch (opt) { /* Command line option character */
+
+#if COMPILER == GNUC
+ case '$': /* Forbid '$' in identifier */
+ option_flags.dollar_in_name = FALSE;
+ break;
+#endif
+
+ case '+':
+#if COMPILER == GNUC
+ plus:
+#endif
+ if (cplus_val || sflag) {
+ mcpp_fputs( "warning: -+ option is ignored\n", ERR);
+ break;
+ }
+ cplus_val = CPLUS;
+ break;
+#if COMPILER == GNUC
+ case '-':
+ if (memcmp( mcpp_optarg, "sysroot", 7) == 0) {
+ if (mcpp_optarg[ 7] == '=') /* --sysroot=DIR */
+ sysroot = mcpp_optarg + 8;
+ else if (mcpp_optarg[ 7] == EOS) /* --sysroot DIR */
+ sysroot = argv[ mcpp_optind++];
+ else
+ usage( opt);
+ break;
+ } else {
+ usage( opt);
+ }
+#endif
+ case '2': /* Reverse digraphs recognition */
+ option_flags.dig = ! option_flags.dig;
+ break;
+ case '3': /* Reverse trigraph recogniion */
+ option_flags.trig = ! option_flags.trig;
+ break;
+
+ case '@': /* Special preprocessing mode */
+ old_mode = mcpp_mode;
+ if (str_eq( mcpp_optarg, "post")
+ || str_eq( mcpp_optarg, "poststd"))
+ mcpp_mode = POST_STD; /* 'post-Standard' mode */
+ else if (str_eq( mcpp_optarg, "old")
+ || str_eq( mcpp_optarg, "oldprep"))
+ mcpp_mode = OLD_PREP; /* 'old-Preprocessor' mode */
+ else if (str_eq( mcpp_optarg, "kr"))
+ mcpp_mode = KR; /* 'K&R 1st' mode */
+ else if (str_eq( mcpp_optarg, "std"))
+ mcpp_mode = STD; /* 'Standard' mode (default)*/
+ else if (str_eq( mcpp_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", mcpp_optarg);
+ break;
+
+#if COMPILER == GNUC
+ case 'A': /* Ignore -A system(gnu), -A cpu(vax) or so */
+ break;
+ case 'a':
+ if (str_eq( mcpp_optarg, "nsi")) { /* -ansi */
+ look_and_install( "__STRICT_ANSI__", DEF_NOARGS_PREDEF, null
+ , "1");
+ ansi = TRUE;
+ break;
+ } else if (memcmp( mcpp_optarg, "uxbase", 6) == 0) {
+ mcpp_optind++;
+ break; /* Ignore '-auxbase some' or such nonsence */
+#if SYSTEM == SYS_MAC
+ } else if (str_eq( mcpp_optarg, "rch")) { /* -arch */
+ strcpy( arch, argv[ mcpp_optind++]);
+ if (str_eq( arch, "ppc") || str_eq( arch, "ppc7400")
+ || str_eq( arch, "ppc64")
+ || str_eq( arch, "i386") || str_eq( arch, "i686")
+ || str_eq( arch, "x86_64") || str_eq( arch, "amd64")) {
+ if (str_eq( arch, "i686"))
+ strcpy( arch, "i386");
+ else if (str_eq( arch, "amd64"))
+ strcpy( arch, "x86_64");
+ else if (str_eq( arch, "ppc7400"))
+ strcpy( arch, "ppc");
+ break;
+ } /* Else usage() */
+#endif
+ }
+ usage( opt);
+#elif COMPILER == MSC
+ case 'a':
+ if (memcmp( mcpp_optarg, "rch", 3) == 0) {
+ if (str_eq( mcpp_optarg + 3, ":SSE") /* -arch:SSE */
+ || str_eq( mcpp_optarg + 3, ":sse"))
+ sse = 1;
+ else if (str_eq( mcpp_optarg + 3, ":SSE2") /* -arch:SSE2 */
+ || str_eq( mcpp_optarg + 3, ":sse2"))
+ sse = 2;
+ /* Else ignore */
+ } else {
+ usage( opt);
+ }
+ break;
+
+ case 'A':
+ option_flags.lang_asm = TRUE; /* "assembler" source */
+ break;
+#else
+ case 'a':
+ option_flags.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 */
+ option_flags.c = TRUE;
+ break;
+
+#if COMPILER == GNUC
+ case 'c':
+ if (! integrated_cpp)
+ usage( opt);
+ break; /* Else ignore this option */
+ case 'd':
+ if (str_eq( mcpp_optarg, "M")) { /* -dM */
+ dMflag = TRUE;
+ no_output++;
+ } else if (str_eq( mcpp_optarg, "D")) { /* -dD */
+ dDflag = TRUE;
+ } else if (str_eq( mcpp_optarg, "igraphs")) { /* -digraphs */
+ option_flags.dig = TRUE;
+ } else if (str_eq( mcpp_optarg, "umpbase")) { /* -dumpbase */
+ ; /* Ignore */
+ } else {
+ usage( opt);
+ }
+ break;
+#endif /* COMPILER == GNUC */
+
+ case 'D': /* Define symbol */
+ if (def_cnt >= MAX_DEF) {
+ mcpp_fputs( "Too many -D options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ def_list[ def_cnt++] = mcpp_optarg;
+ break;
+
+ case 'e':
+ /* Change the default MBCHAR encoding */
+ if (set_encoding( mcpp_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 (memcmp( mcpp_optarg, "input-charset=", 14) == 0) {
+ /* Treat -finput-charset= as the same option as -e */
+ if (set_encoding( mcpp_optarg + 14, FALSE, 0) == 0)
+ usage( opt);
+ mb_changed = TRUE;
+ } else if (str_eq( mcpp_optarg, "working-directory")) {
+ gcc_work_dir = TRUE;
+ } else if (str_eq( mcpp_optarg, "no-working-directory")) {
+ gcc_work_dir = FALSE;
+ } else if (str_eq( mcpp_optarg, "stack-protector")) {
+ look_and_install( "__SSP__", DEF_NOARGS_PREDEF, null, "1");
+ } else if (str_eq( mcpp_optarg, "stack-protector-all")) {
+ look_and_install( "__SSP_ALL__", DEF_NOARGS_PREDEF, null, "2");
+ } else if (str_eq( mcpp_optarg, "exceptions")) {
+ look_and_install( "__EXCEPTIONS", DEF_NOARGS_PREDEF, null
+ , "1");
+ } else if (str_eq( mcpp_optarg, "no-exceptions")) {
+ undef_list[ undef_cnt++] = "__EXCEPTIONS";
+ } else if (str_eq( mcpp_optarg, "PIC")
+ || str_eq( mcpp_optarg, "pic")
+ || str_eq( mcpp_optarg, "PIE")
+ || str_eq( mcpp_optarg, "pie")) {
+ look_and_install( "__PIC__", DEF_NOARGS_PREDEF, null, "1");
+ look_and_install( "__pic__", DEF_NOARGS_PREDEF, null, "1");
+ } else if (str_eq( mcpp_optarg, "no-dollars-in-identifiers")) {
+ option_flags.dollar_in_name = FALSE;
+ } else if (str_eq( mcpp_optarg, "no-show-column")) {
+ ; /* Ignore this option */
+ } else if (! integrated_cpp) {
+ usage( opt);
+ }
+ break;
+
+ case 'g':
+ if (!isdigit( *mcpp_optarg)
+ && str_eq( argv[ mcpp_optind - 2], "-g"))
+ /* Neither '-g 0' nor '-ggdb' -- No argument */
+ mcpp_optind--;
+ break; /* Ignore the option */
+#elif COMPILER == LCC
+ case 'g': /* Define __LCCDEBUGLEVEL as <n> */
+ if (*(mcpp_optarg + 1) == EOS && isdigit( *mcpp_optarg)) {
+ defp = look_id( debug_name);
+ strcpy( defp->repl, mcpp_optarg);
+ } else {
+ usage( opt);
+ }
+ break;
+#elif COMPILER == MSC
+ case 'G':
+ if (*(mcpp_optarg + 1) == EOS) { /* -Gx */
+ switch (*mcpp_optarg) {
+ case '3': case '4': case '5': case '6':
+ gval = *mcpp_optarg;
+ break;
+ case 'B': /* -GB */
+ gval = '6';
+ break;
+ case 'R':
+ look_and_install( "_CPPRTTI", DEF_NOARGS_PREDEF, null
+ , "1");
+ break;
+ case 'X':
+ look_and_install( "_CPPUNWIND", DEF_NOARGS_PREDEF, null
+ , "1");
+ break;
+ case 'Z':
+ look_and_install( "__MSVC_RUNTIME_CHECKS"
+ , DEF_NOARGS_PREDEF, null, "1");
+ break;
+ default :
+ mcpp_fprintf( ERR, warning, opt, mcpp_optarg);
+ }
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+#if SYSTEM == SYS_MAC
+ case 'F':
+ framework[ num_framework++] = mcpp_optarg;
+ break;
+#endif
+
+ case 'h':
+ if (*(mcpp_optarg + 1) == EOS && isdigit( *mcpp_optarg))
+ /* a digit */
+ look_and_install( "__STDC_HOSTED__", DEF_NOARGS_PREDEF, null
+ , mcpp_optarg);
+ else
+ usage( opt);
+ break;
+
+#if COMPILER == MSC
+ case 'X':
+ unset_sys_dirs = TRUE;
+ break;
+#endif
+ case 'I': /* Include directory */
+ if (str_eq( mcpp_optarg, "-")) { /* -I- */
+#if COMPILER == GNUC
+ sys_dirp = incend; /* Split include directories */
+ i_split = TRUE;
+#else
+ unset_sys_dirs = TRUE;
+ /* Unset pre-specified include directories */
+#endif
+ } else if (*(mcpp_optarg + 1) == EOS && isdigit( *mcpp_optarg)
+ && (i = *mcpp_optarg - '0') != 0
+ && (i & ~(CURRENT | SOURCE)) == 0) {
+ search_rule = i; /* -I1, -I2 or -I3 */
+ } else { /* Not '-' nor a digit */
+ set_a_dir( mcpp_optarg); /* User-defined dir */
+ }
+ break;
+
+#if COMPILER == MSC
+ case 'F':
+ if (str_eq( mcpp_optarg, "l")) { /* -Fl */
+ if (preinc_end >= &preinclude[ NPREINCLUDE]) {
+ mcpp_fputs( "Too many -Fl options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ *preinc_end++ = argv[ mcpp_optind++];
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+#if COMPILER == GNUC
+ case 'i':
+ if (str_eq( mcpp_optarg, "nclude")) { /* -include */
+ if (preinc_end >= &preinclude[ NPREINCLUDE]) {
+ mcpp_fputs( "Too many -include options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ *preinc_end++ = argv[ mcpp_optind++];
+ } else if (str_eq( mcpp_optarg, "system")) { /* -isystem */
+ if (sysdir_end >= &sysdir[ NSYSDIR]) {
+ mcpp_fputs( "Too many -isystem options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ *sysdir_end++ = argv[ mcpp_optind++];
+ /* Add the directory before system include directory*/
+ } else if (str_eq( mcpp_optarg, "quote")) { /* -iquote */
+ if (quote_dir_end >= &quote_dir[ N_QUOTE_DIR]) {
+ mcpp_fputs( "Too many -iquote options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ *quote_dir_end++ = argv[ mcpp_optind++];
+ /* Add the directory for #include "header" */
+ } else if (memcmp( mcpp_optarg, "sysroot", 7) == 0) {
+ if (mcpp_optarg[ 7] == '=') /* -isysroot=DIR */
+ sysroot = mcpp_optarg + 8;
+ else if (mcpp_optarg[ 7] == EOS) /* -isysroot DIR */
+ sysroot = argv[ mcpp_optind++];
+ else
+ usage( opt);
+ } else if (str_eq( mcpp_optarg, "prefix") /* -iprefix */
+ || str_eq( mcpp_optarg, "withprefix") /* -iwithprefix */
+ || str_eq( mcpp_optarg, "withprefixbefore")
+ /* -iwithprefixbefore */
+ || str_eq( mcpp_optarg, "dirafter") /* -idirafter */
+ || str_eq( mcpp_optarg, "multilib")) { /* -imultilib */
+ mcpp_optind++; /* Skip the argument */
+ /* Ignore these options */
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+ case 'j':
+ option_flags.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_PREDEF, null, "1");
+ break;
+#endif
+
+ case 'K':
+ mcpp_debug |= MACRO_CALL;
+ /*
+ * Putout macro expansion informations embedded in comments.
+ * Same with '#pragma MCPP debug macro_call'.
+ */
+ /* Enable white spaces preservation, too */
+ /* Fall through */
+ case 'k':
+ option_flags.k = TRUE;
+ /* Keep white spaces of input lines as they are */
+ break;
+
+#if COMPILER == GNUC
+ case 'l':
+ if (memcmp( mcpp_optarg, "ang-", 4) != 0) {
+ usage( opt);
+ } else if (str_eq( mcpp_optarg + 4, "c")) { /* -lang-c */
+ ; /* Ignore this option */
+ } else if (str_eq( mcpp_optarg + 4, "c99") /* -lang-c99*/
+ || str_eq( mcpp_optarg + 4, "c9x")) { /* -lang-c9x*/
+ if (! sflag) {
+ stdc_val = 1; /* Define __STDC__ to 1 */
+ std_val = 199901L;
+ sflag = TRUE;
+ }
+ } else if (str_eq( mcpp_optarg + 4, "c89")) { /* -lang-c89*/
+ if (! sflag) {
+ stdc_val = 1; /* Define __STDC__ to 1 */
+ sflag = TRUE;
+ }
+ } else if (str_eq( mcpp_optarg + 4, "c++")) { /* -lang-c++*/
+ goto plus;
+ } else if (str_eq( mcpp_optarg + 4, "asm")) { /* -lang-asm*/
+ option_flags.lang_asm = TRUE;
+ } else {
+ usage( opt);
+ }
+ break;
+#endif /* COMPILER == GNUC */
+
+ case 'M': /* Output source file dependency line */
+ if (str_eq( mcpp_optarg, "M")) { /* -MM */
+ ;
+ } else if (str_eq( mcpp_optarg, "D")) { /* -MD */
+ mkdep |= (MD_SYSHEADER | MD_FILE);
+ } else if (str_eq( mcpp_optarg, "MD")) { /* -MMD */
+ mkdep |= MD_FILE;
+ } else if (str_eq( mcpp_optarg, "P")) { /* -MP */
+ mkdep |= MD_PHONY;
+ } else if (str_eq( mcpp_optarg, "Q")) { /* -MQ target */
+ mkdep |= MD_QUOTE;
+ mkdep_mq = argv[ mcpp_optind++];
+ } else if (str_eq( mcpp_optarg, "T")) { /* -MT target */
+ mkdep_mt = argv[ mcpp_optind++];
+ } else if (str_eq( mcpp_optarg, "F")) { /* -MF file */
+ mkdep_mf = argv[ mcpp_optind++];
+ } else if (argv[ mcpp_optind - 1] == mcpp_optarg) { /* -M */
+ mkdep |= MD_SYSHEADER;
+ mcpp_optind--;
+ } else {
+ usage( opt);
+ }
+ if (str_eq( mcpp_optarg, "D") || str_eq( mcpp_optarg, "MD")) {
+ cp = argv[ mcpp_optind];
+ if (cp && *cp != '-') /* -MD (-MMD) file */
+ mkdep_md = argv[ mcpp_optind++];
+ }
+ mkdep |= MD_MKDEP;
+ break;
+
+#if SYS_FAMILY == SYS_UNIX
+ case 'm':
+ if (str_eq( mcpp_optarg, "64")) { /* -m64 */
+ if (str_eq( CPU, "i386"))
+ ACE_OS::strcpy( arch, "x86_64");
+ else if (str_eq( CPU, "ppc"))
+ ACE_OS::strcpy( arch, "ppc64");
+ /* Else ignore */
+ break;
+ } else if (str_eq( mcpp_optarg, "32")) { /* -m32 */
+ if (str_eq( CPU, "x86_64"))
+ ACE_OS::strcpy( arch, "i386");
+ else if (str_eq( CPU, "ppc64"))
+ ACE_OS::strcpy( arch, "ppc");
+ /* Else ignore */
+ break;
+ } else if (str_eq( mcpp_optarg, "mmx")) { /* -mmmx */
+ look_and_install( "__MMX__", DEF_NOARGS_PREDEF, null, "1");
+ break;
+ } else if (str_eq( mcpp_optarg, "no-mmx")) { /* -mno-mmx */
+ undef_list[ undef_cnt++] = "__MMX__";
+ break;
+ }
+#endif /* SYS_FAMILY == UNIX */
+#if COMPILER == GNUC
+#if SYSTEM == SYS_CYGWIN
+ if (str_eq( mcpp_optarg, "no-cygwin")) { /* -mno-cygwin */
+ no_cygwin = TRUE;
+ break;
+ }
+#endif
+ if (! integrated_cpp)
+ usage( opt);
+ break;
+
+ case 'u':
+ if (! str_eq( mcpp_optarg, "ndef")) /* -undef */
+ usage( opt); /* Else fall through */
+#endif /* COMPILER == GNUC */
+
+#if COMPILER == MSC
+ case 'u':
+#endif
+ case 'N':
+ /* No predefines: remove "unix", "__unix__" and friends. */
+ nflag = TRUE;
+ break;
+
+#if COMPILER == GNUC || NO_DIR
+ case 'n':
+#if NO_DIR
+ if (str_eq( mcpp_optarg, "odir")) { /* -nodir */
+ no_dir = TRUE;
+ }
+#endif
+#if COMPILER == GNUC
+ if (str_eq( mcpp_optarg, "ostdinc")) { /* -nostdinc */
+ unset_sys_dirs = TRUE; /* Unset pre-specified directories */
+ } else if (str_eq( mcpp_optarg, "ostdinc++")) { /* -nostdinc++ */
+ set_cplus_dir = FALSE; /* Unset C++-specific directories */
+ } else if (str_eq( mcpp_optarg, "oprecomp")) { /* -noprecomp */
+ mcpp_fprintf( ERR, warning, opt, mcpp_optarg);
+ break;
+ }
+#endif
+ else {
+ usage( opt);
+ }
+ break;
+#endif
+
+#if COMPILER == GNUC
+ case 'O':
+ if (integrated_cpp) {
+ if (*mcpp_optarg == '-') /* No argument */
+ mcpp_optind--;
+ else if ((isdigit( *mcpp_optarg) && *mcpp_optarg != '0')
+ || *mcpp_optarg == 's' || *mcpp_optarg == 'z')
+ /* -O1, -O2 -Os, -Oz */
+ look_and_install( "__OPTIMIZE__", DEF_NOARGS_PREDEF, null
+ , "1");
+ else if (! isdigit( *mcpp_optarg))
+ usage( opt);
+ /* Else -O0: ignore */
+ } 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 = mcpp_optarg; /* Output file name */
+ break;
+
+ case 'P': /* No #line output */
+ option_flags.p = TRUE;
+ break;
+
+#if COMPILER == GNUC
+ case 'p':
+ if (str_eq( mcpp_optarg, "edantic") /* -pedantic */
+ || str_eq( mcpp_optarg, "edantic-errors")) {
+ /* -pedantic-errors */
+ /* This option does not imply -ansi */
+ 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( mcpp_optarg, "uiet"))
+ /* -quiet: GCC's undocumented, yet frequently specified opt */
+ break; /* Ignore the option */
+ else
+ usage( opt);
+ break;
+#endif /* COMPILER == GNUC */
+
+ case 'Q':
+ option_flags.q = TRUE;
+ break;
+
+#if COMPILER == MSC
+ case 'R': /* -RTC1, -RTCc, -RTCs, -RTCu, etc. */
+ if (memcmp( mcpp_optarg, "TC", 2) == 0
+ && *(mcpp_optarg + 2) != EOS)
+ look_and_install( "__MSVC_RUNTIME_CHECKS", DEF_NOARGS_PREDEF
+ , null, "1");
+ else
+ usage( opt);
+ break;
+#endif
+
+ case 'S':
+ if (cplus_val || sflag) { /* C++ or the second time */
+ mcpp_fprintf( ERR, warning, opt, mcpp_optarg);
+ break;
+ }
+ i = *mcpp_optarg;
+ if (! isdigit( i) || *(mcpp_optarg + 1) != EOS)
+ usage( opt);
+ stdc_val = i - '0';
+ sflag = TRUE;
+ break;
+
+#if COMPILER == GNUC
+ case 'r':
+ if (str_eq( mcpp_optarg, "emap"))
+ mcpp_fprintf( ERR, warning, opt, mcpp_optarg);
+ /* Ignore -remap option */
+ else
+ usage( opt);
+ break;
+
+ case 's':
+ if (memcmp( mcpp_optarg, "td=", 3) == 0
+ && ACE_OS::strlen( mcpp_optarg) > 3) { /* -std=STANDARD*/
+ cp = mcpp_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 (memcmp( cp, "iso9899:", 8) == 0
+ && ACE_OS::strlen( cp) >= 14) { /* std=iso9899:199409, etc. */
+ mcpp_optarg = cp + 8;
+ look_and_install( "__STRICT_ANSI__", DEF_NOARGS_PREDEF
+ , null, "1");
+ ansi = TRUE;
+ goto Version;
+ } else if (memcmp( cp, "iso14882", 8) == 0) {
+ cp += 8;
+ ansi = TRUE;
+ if (cp && *cp == ':' && ACE_OS::strlen( cp) >= 7) {
+ /* std=iso14882:199711, etc. */
+ cplus_val = CPLUS;
+ mcpp_optarg = cp + 1;
+ goto Version;
+ } else {
+ goto plus;
+ }
+ } else {
+ usage( opt);
+ }
+ if (! cplus_val && memcmp( cp, "gnu", 3) != 0) {
+ /* 'std=gnu*' does not imply -ansi */
+ look_and_install( "__STRICT_ANSI__", DEF_NOARGS_PREDEF
+ , null, "1");
+ ansi = TRUE;
+ }
+ stdc_val = 1;
+ sflag = TRUE;
+ } else {
+ usage( opt);
+ }
+ break;
+
+ case 't':
+ if (str_eq( mcpp_optarg, "raditional")
+ || str_eq( mcpp_optarg, "raditional-cpp")) {
+ /* -traditional, -traditional-cpp */
+ trad = TRUE;
+ mcpp_mode = OLD_PREP;
+ } else if (str_eq( mcpp_optarg, "rigraphs")) {
+ option_flags.trig = TRUE; /* -trigraphs */
+ } else {
+ usage( opt);
+ }
+ break;
+#endif /* COMPILER == GNUC */
+
+#if COMPILER == MSC
+ case 'T':
+ if (ACE_OS::strlen( mcpp_optarg) > 1)
+ usage( opt);
+ i = tolower( *mcpp_optarg); /* Fold case */
+ if (i == 'c') {
+ ; /* Ignore this option */
+ } else if (i == 'p') {
+ cplus_val = CPLUS;
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+ case 'U': /* Undefine macro */
+ if (undef_cnt >= MAX_UNDEF) {
+ mcpp_fputs( "Too many -U options.\n", ERR);
+ longjmp( error_exit, -1);
+ }
+ undef_list[ undef_cnt++] = mcpp_optarg;
+ break;
+
+ case 'V':
+#if COMPILER == GNUC
+ Version:
+#endif
+ valp = eval_num( mcpp_optarg);
+ if (valp->sign == VAL_ERROR)
+ usage( opt);
+ std_val = (long) valp->val;
+ break;
+
+ case 'v':
+ option_flags.v = TRUE;
+ show_path = TRUE;
+ break;
+
+ case 'W': /* warning level */
+ if (warn_level == -1) /* Have to initialize */
+ warn_level = 0;
+#if COMPILER == GNUC
+ if (argv[ mcpp_optind - 1] == mcpp_optarg) { /* No argument */
+ /*
+ * Note: -W without argument is not officially supported.
+ * It may cause an error.
+ */
+ warn_level |= (1 | 2 | 4 | 16);
+ mcpp_optind--;
+ } else if (str_eq( mcpp_optarg, "comment")
+ || str_eq( mcpp_optarg, "comments")
+ || str_eq( mcpp_optarg, "sign-compare")) {
+ warn_level |= 1;
+ } else if (str_eq( mcpp_optarg, "undef")) {
+ warn_level |= 4;
+ } else if (str_eq( mcpp_optarg, "all")) {
+ warn_level |= (1 | 16); /* Convert -Wall to -W17*/
+ } else if (str_eq( mcpp_optarg, "trigraphs")) {
+ warn_level |= 16;
+ }
+#endif /* COMPILER == GNUC */
+#if COMPILER == MSC
+ if (str_eq( mcpp_optarg, "all")) {
+ warn_level |= (1 | 16); /* Convert -Wall to -W17*/
+ } else if (str_eq( mcpp_optarg, "L")) {
+ option_flags.no_source_line = TRUE;
+ /* Single-line diagnostic */
+ }
+#endif
+ if (isdigit( *mcpp_optarg)) {
+ warn_level |= parse_warn_level( mcpp_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( mcpp_optarg, "c")) {
+ break; /* -x c -- ignore this */
+ } else if (str_eq( mcpp_optarg, "c++")) {
+ goto plus;
+ } else if (str_eq( mcpp_optarg, "assembler-with-cpp")) {
+ option_flags.lang_asm = TRUE;
+ break;
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+#if COMPILER == MSC
+ case 'Z':
+ if (str_eq( mcpp_optarg, "c:wchar_t")) { /* -Zc:wchar_t */
+ look_and_install( "_NATIVE_WCHAR_T_DEFINED", DEF_NOARGS_PREDEF
+ , null, "1");
+ look_and_install( "_WCHAR_T_DEFINED", DEF_NOARGS_PREDEF, null
+ , "1");
+ wchar_t_modified = TRUE;
+ } else if (str_eq( mcpp_optarg, "c:wchar_t-")) {/* -Zc:wchar_t- */
+ wchar_t_modified = TRUE; /* Do not define the macros */
+ } else if (str_eq( mcpp_optarg, "l")) {
+ look_and_install( "_VC_NODEFAULTLIB", DEF_NOARGS_PREDEF, null
+ , "1");
+ } else if (str_eq( mcpp_optarg, "a")) { /* -Za */
+ undefine( "_MSC_EXTENSIONS");
+ option_flags.dollar_in_name = FALSE;
+ } else if (str_eq( mcpp_optarg, "e")) {
+ /* Ignore -Ze silently */
+ break;
+ } else if (*(mcpp_optarg + 1) == EOS) {
+ /* -Z followed by one char */
+ mcpp_fprintf( ERR, warning, opt, mcpp_optarg);
+ /* Ignore the option with warning */
+ } else {
+ usage( opt);
+ }
+ break;
+#endif
+
+ case 'z':
+ option_flags.z = TRUE; /* No output of included file */
+ break;
+
+ default: /* What is this one? */
+ usage( opt);
+ break;
+ } /* Switch on all options */
+
+ } /* For all arguments */
+
+ if (mcpp_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, 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 SYSTEM == SYS_MAC
+ set_a_dir( 0); /* Initialize incdir[] */
+ to_search_framework = incend;
+ /* Search framework[] next to the directory */
+#endif
+
+#if COMPILER == GNUC && SYSTEM == SYS_MAC
+ if (arch[ 0]) { /* -arch option has been specified */
+ if (((str_eq( CPU, "i386") || str_eq( CPU, "x86_64"))
+ && (! str_eq( arch, "i386") && ! str_eq( arch, "x86_64")))
+ || ((str_eq( CPU, "ppc") || str_eq( CPU, "ppc64"))
+ && (! str_eq( arch, "ppc") && ! str_eq( arch, "ppc64")))) {
+ mcpp_fprintf( ERR, "Wrong argument of -arch option: %s\n", arch);
+ longjmp( error_exit, -1);
+ }
+ }
+#endif
+ if (! arch[ 0]) {
+ /* None of -arch, -m32 or -m64 options has been specified. */
+ /* The CPU-specific-macros will be defined in init_cpu_macro(). */
+ ACE_OS::strcpy( arch, CPU);
+ }
+#if COMPILER != GNUC
+ init_cpu_macro( gval, sse);
+#endif
+
+#if COMPILER == GNUC
+ if (sysdir < sysdir_end) {
+ char ** dp = sysdir;
+ if (! sys_dirp || sys_dirp == incdir)
+ sys_dirp = dp;
+ while (dp < sysdir_end)
+ set_a_dir( *dp++);
+ }
+ if (*in_pp && str_eq( (*in_pp) + ACE_OS::strlen( *in_pp) - 2, ".S"))
+ option_flags.lang_asm = TRUE; /* Input file name is *.S */
+ if (option_flags.lang_asm) {
+ look_and_install( "__ASSEMBLER__", DEF_NOARGS_PREDEF, null, "1");
+ option_flags.dollar_in_name = FALSE; /* Disable '$' in name */
+ }
+ if (! sys_dirp || sys_dirp == incdir)
+ sys_dirp = incend;
+#endif
+#if SYSTEM == SYS_MAC
+ init_framework(); /* After setting sys_dirp */
+#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;
+
+ /* Normalize the path-list */
+ if (*in_pp && ! str_eq( *in_pp, "-")) {
+ char * tmp = norm_path( null, *in_pp, FALSE, FALSE);
+ if (tmp) /* The file exists */
+ *in_pp = tmp;
+ /* Else mcpp_main() will diagnose *in_pp and exit */
+ }
+ if (! (mcpp_debug & MACRO_CALL)) {
+ /* -K option alters behavior of -v option */
+ if (option_flags.v)
+ version();
+ if (show_path) {
+ fp_debug = stderr;
+ dump_path();
+ fp_debug = stdout;
+ }
+ }
+}
+
+static void version( void)
+/*
+ * Print version message.
+ */
+{
+ const char * mes[] = {
+
+#ifdef MCPP_LIB
+ /* Write messages here, for example, "MySomeTool with ". */
+#endif
+
+#ifdef VERSION_MSG
+ "MCPP V.2.7.2 (2008/11) "
+#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;
+ 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 SYSTEM == SYS_MAC && COMPILER == GNUC
+ "-arch <arch> Change the target to <arch> (i386, x86_64, ppc, ppc64).\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 SYSTEM == SYS_MAC
+ "-F <framework> Add <framework> to top of framework directory list.\n",
+#endif
+#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",
+
+#if COMPILER == GNUC
+ "-isysroot <dir> Change root of system header directory to <dir>.\n",
+ "-include <file> Include the <file> prior to the main input file.\n",
+#else
+ "-I- Unset system or site specific include directories.\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",
+#if SYS_FAMILY == SYS_UNIX
+ "-m32 Change target CPU from x86_64, ppc64 to i386, ppc, respectively.\n",
+ "-m64 Change target CPU from i386, ppc to x86_64, ppc64, respectively.\n",
+#endif
+ "-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",
+ "-S <n> Redefine __STDC__ to <n>.\n",
+#else
+ "-S <n> Redefine __STDC__ to <n>, undefine old style macros.\n",
+#endif
+
+#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
+ "-K Output macro annotations embedding in comments.\n",
+#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
+
+ "-k Keep white spaces of input lines as they are.\n",
+
+ "\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, mcpp_optarg ? mcpp_optarg : null);
+ version();
+#ifdef 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 SYS_FAMILY == SYS_UNIX
+ "m:",
+#endif
+
+#if COMPILER == GNUC
+ "$A:a:cd:Ef:g:i:l:r:s:t:u:O:p:q:wx:",
+#elif COMPILER == MSC
+ "Aa:F:G:JR:T:XZ:uw",
+#elif COMPILER == LCC
+ "g:O",
+#endif
+
+#if COMPILER != GNUC && COMPILER != MSC
+ "a",
+#endif
+#if SYSTEM == SYS_MAC
+ "F:-:",
+#endif
+
+ 0
+ };
+
+ const char * const * lp = & list[ 0];
+
+ ACE_OS::strcpy( optlist, "23+@:e:h:jkn:o:vzCD:I:KM: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 * mcpp_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 = mcpp_optarg;
+ int w, i;
+
+ w = i = 0;
+ while( *cp != EOS) {
+ while( *cp == ' ')
+ cp++; /* Skip spaces */
+ if (! isdigit( *cp))
+ break; /* Error */
+ while (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"
+ , mcpp_optarg);
+ usage( opt);
+ }
+ w |= i; /* Take the last arg */
+ return w;
+}
+
+static void def_a_macro(int opt, /* 'D' */
+ char * def /* Argument of -D option */
+ )
+/*
+ * 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 && option_flags.trig)
+ cnv_trigraph( def);
+ if (mcpp_mode == POST_STD && option_flags.dig)
+ cnv_digraph( def); /* Convert prior to installing macro */
+ definition = (char *)ACE_OS::malloc( ACE_OS::strlen( def) + 6);
+ ACE_OS::strcpy( definition, def);
+ if ((cp = ACE_OS::strchr( definition, '=')) != 0) {
+ *cp = ' '; /* Remove the '=' */
+ // cp = "\n"; /* Append <newline> */
+ *(cp + 0) = '\n';
+ *(cp + 1) = '\0';
+ } else {
+ cp = ACE_OS::strlen (def) + definition;
+ *(cp + 0) = ' ';
+ *(cp + 1) = '1';
+ *(cp + 2) = '\n';
+ *(cp + 3) = '\0';
+ //cp = " 1\n"; /* With definition "1" */
+ }
+ cp = definition;
+ while ((char_type[ *cp & UCHARMAX] & SPA) == 0)
+ cp++;
+ i = *cp;
+ *cp = EOS;
+ if ((defp = look_id( definition)) != 0) /* Pre-defined */
+ undefine( definition);
+ *cp = i;
+ /* Now, save the definition. */
+ unget_string( definition, 0);
+ if (do_define( FALSE, 0) == 0) /* Define a macro */
+ usage( opt);
+ *cp = EOS;
+ if (str_eq( definition, "__STDC__")) {
+ defp = look_id( definition);
+ defp->nargs = DEF_NOARGS_STANDARD;
+ /* 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 */
+ 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 COMPILER == GNUC
+ if (sflag || cplus_val || ansi || std_val != -1L)
+#else
+ if (sflag || cplus_val || std_val != -1L)
+#endif
+ incompat = TRUE;
+ if (option_flags.dig) {
+ if (option_flags.dig != DIGRAPHS_INIT)
+ incompat = TRUE;
+ else
+ option_flags.dig = 0;
+ }
+ break;
+ }
+
+ if (mcpp_mode == POST_STD
+ && (option_flags.lang_asm || compat_mode || option_flags.k))
+ incompat = TRUE;
+ if (mcpp_mode != STD && option_flags.trig) {
+ if (option_flags.trig != TRIGRAPHS_INIT)
+ incompat = TRUE;
+ else
+ option_flags.trig = FALSE;
+ }
+ if (mcpp_mode != STD && (mcpp_debug & MACRO_CALL))
+ incompat = TRUE;
+ if ((mcpp_debug & MACRO_CALL)
+ && (option_flags.lang_asm || option_flags.c)) {
+ mcpp_fputs( "Disabled -K option.\n", ERR);
+ mcpp_debug &= ~MACRO_CALL;
+ /* -a and -C options do not co-exist with -K */
+ }
+ 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 */
+ if (mcpp_mode != STD)
+ char_type[ MAC_INF] = 0;
+
+ expand_init( compat_mode, ansi);
+ /* Set function pointer to macro expansion routine */
+}
+
+#if COMPILER != GNUC
+
+static void init_cpu_macro (
+ int gval, /* Argument of -G option for MSC */
+ int sse /* Argument of -sse: option for MSC */
+ )
+/*
+ * Set predefined macros for CPU.
+ * This routine is called from do_options() only once.
+ * GCC-specific-build defines these macro by init_gcc_macro().
+ */
+{
+ ACE_UNUSED_ARG (gval);
+ ACE_UNUSED_ARG (sse);
+
+ const char * cpu_macro[][ 7] = {
+#if SYS_FAMILY == SYS_UNIX
+ { "__i386__"
+#if SYSTEM == SYS_CYGWIN
+ , "_X86_"
+#endif
+ , 0,},
+ { "__x86_64__", "__amd64__", 0,},
+ { "__ppc__", "__powerpc__", 0,},
+ { "__ppc64__", "__powerpc64__", 0,}
+#elif SYS_FAMILY == SYS_WIN
+ { "_WIN32", "__WIN32__", "_X86_"
+#if SYSTEM == SYS_MINGW
+ , "__i386__"
+#endif
+ , 0,},
+ { "_WIN32", "_WIN64", "__WIN64__", "_M_AMD64", "_AMD64_", "_X64_"
+ , 0,}, /* "_WIN32" is defined even on Windows 64 */
+ { 0,}, /* Not supported */
+ { 0,} /* Not supported */
+#endif
+ };
+ const char ** macro;
+ int index;
+
+ if (str_eq( arch, "i386"))
+ index = 0;
+ else if (str_eq( arch, "x86_64"))
+ index = 1;
+ else if (str_eq( arch, "ppc"))
+ index = 2;
+ else if (str_eq( arch, "ppc64"))
+ index = 3;
+ else
+ index = 9;
+
+ if (index == 9) { /* Unknown CPU */
+ look_and_install( "__" CPU "__", DEF_NOARGS_PREDEF, null, "1");
+ return;
+ }
+ macro = cpu_macro[ index];
+ while (*macro)
+ look_and_install( *macro++, DEF_NOARGS_PREDEF, null, "1");
+#if SYS_FAMILY == SYS_WIN
+ if (index == 0) {
+ char val[] = "600";
+ if (gval)
+ val[ 0] = gval;
+ look_and_install( "_M_IX86", DEF_NOARGS_PREDEF, null, val);
+ val[ 0] = '0' + sse;
+ val[ 1] = '\0';
+ look_and_install( "_M_IX86_FP", DEF_NOARGS_PREDEF, null, val);
+ }
+#endif
+}
+#endif /* COMPILER != GNUC */
+
+static void init_predefines( void)
+/*
+ * Set or unset predefined macros.
+ */
+{
+ 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);
+ } else if (stdc_val || cplus_val) {
+#if COMPILER != GNUC
+ un_predefine( FALSE); /* Undefine "unix" or so */
+#endif
+ }
+ ACE_OS::sprintf( tmp, "%ldL", cplus_val ? cplus_val : stdc_ver);
+ if (cplus_val) {
+ look_and_install( "__cplusplus", DEF_NOARGS_STANDARD, null, tmp);
+ } else {
+ if (stdc_ver)
+ look_and_install( "__STDC_VERSION__", DEF_NOARGS_STANDARD, 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 are initialized with magic argument counts.
+ * expand_macro() notices this and calls the appropriate routine.
+ * DEF_NOARGS is one greater than the first "magic" definition.
+ * 'DEF_NOARGS - n' are 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_DYNAMIC - 1, null, "-1234567890");
+ /* Room for 11 chars (10 for long and 1 for '-' in case of wrap round. */
+ look_and_install( "__FILE__", DEF_NOARGS_DYNAMIC - 2, 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_DYNAMIC, null, timestr);
+ ACE_OS::sprintf( timestr, "\"%.8s\"", tstring + 11);
+ look_and_install( "__TIME__", DEF_NOARGS_DYNAMIC, 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_PREDEF, 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_STANDARD, null, tmp);
+ }
+}
+
+static void set_limit( void)
+/*
+ * Set the minimum translation limits specified by the Standards.
+ */
+{
+ if (cplus_val) { /* Specified by C++ 1998 Standard */
+ std_limits.str_len = SLEN_CPLUS_MIN;
+ std_limits.id_len = IDLEN_CPLUS_MIN;
+ std_limits.n_mac_pars = NMACPARS_CPLUS_MIN;
+ std_limits.exp_nest = EXP_NEST_CPLUS_MIN;
+ std_limits.blk_nest = BLK_NEST_CPLUS_MIN;
+ std_limits.inc_nest = INCLUDE_NEST_CPLUS_MIN;
+ std_limits.n_macro = NMACRO_CPLUS_MIN;
+ std_limits.line_num = LINE_CPLUS_LIMIT;
+ } else if (stdc_ver >= 199901L) { /* Specified by C 1999 Standard */
+ std_limits.str_len = SLEN99MIN;
+ std_limits.id_len = IDLEN99MIN;
+ std_limits.n_mac_pars = NMACPARS99MIN;
+ std_limits.exp_nest = EXP_NEST99MIN;
+ std_limits.blk_nest = BLK_NEST99MIN;
+ std_limits.inc_nest = INCLUDE_NEST99MIN;
+ std_limits.n_macro = NMACRO99MIN;
+ std_limits.line_num = LINE99LIMIT;
+ } else if (standard) { /* Specified by C 1990 Standard */
+ std_limits.str_len = SLEN90MIN;
+ std_limits.id_len = IDLEN90MIN;
+ std_limits.n_mac_pars = NMACPARS90MIN;
+ std_limits.exp_nest = EXP_NEST90MIN;
+ std_limits.blk_nest = BLK_NEST90MIN;
+ std_limits.inc_nest = INCLUDE_NEST90MIN;
+ std_limits.n_macro = NMACRO90MIN;
+ std_limits.line_num = 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.
+ */
+{
+ const 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 init_sys_macro( void)
+/*
+ * Define system-specific macros and some Standard required macros
+ * and undefine macros specified by -U options.
+ */
+{
+ /* This order is important. */
+
+ def_macros(); /* Define macros specified by -D */
+#if COMPILER == GNUC
+ chk_env();
+#endif
+ init_predefines(); /* Define predefined macros */
+#if COMPILER == GNUC
+ init_gcc_macro();
+#elif COMPILER == MSC
+ init_msc_macro();
+#endif
+ undef_macros(); /* Undefine macros specified by -U */
+ if (mcpp_debug & MACRO_CALL)
+ dump_def( FALSE, TRUE); /* Finally putout current macro names */
+}
+
+void at_start( void)
+/*
+ * Do the commands prior to processing main source file after do_options().
+ */
+{
+ char * env;
+ FILEINFO * file_saved = infile;
+
+ /*
+ * Set multi-byte character encoding according to environment variables
+ * LC_ALL, LC_CTYPE and LANG -- with preference in this order.
+ */
+ if (! mb_changed) { /* -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 (option_flags.dollar_in_name)
+ char_type[ 0x24] |= LET; /* Enable '$' in identifiers */
+ /*
+ * 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.
+ */
+ {
+ char ** preinc;
+ /*
+ * Note: Here, 'infile' is the main input file, which is pseudo-
+ * parent file of the files to pre-include. So, we must
+ * temporarily set the infile's directory to the current directory
+ * in order to preinclude the files relative to it.
+ */
+ preinc = preinc_end;
+ while (preinclude <= --preinc && *preinc != 0)
+ open_file( &null, 0, *preinc, TRUE, TRUE, FALSE);
+ }
+#endif
+
+ put_info( file_saved);
+}
+
+static void put_info(
+ FILEINFO * sharp_file
+ )
+/*
+ * Putout compiler-specific information.
+ */
+{
+ if (no_output || option_flags.p)
+ return;
+ sharp_file->line++;
+ sharp( sharp_file, 0);
+ sharp_file->line--;
+#if COMPILER == GNUC
+ if (gcc_work_dir)
+ mcpp_fprintf( OUT, "%s%ld \"%s%c\"\n"
+ , std_line_prefix ? "#line " : LINE_PREFIX
+ , 1, cur_work_dir, '/');
+ /* Putout the current directory as a #line line as: */
+ /* '# 1 "/abs-path/cur_dir//"'. */
+ mcpp_fprintf( OUT, "%s%ld \"<built-in>\"\n"
+ , std_line_prefix ? "#line " : LINE_PREFIX , 1);
+ mcpp_fprintf( OUT, "%s%ld \"<command line>\"\n"
+ , std_line_prefix ? "#line " : LINE_PREFIX , 1);
+ mcpp_fprintf( OUT, "%s%ld \"%s\"%s\n"
+ , std_line_prefix ? "#line " : LINE_PREFIX, 1, cur_fullname
+ , ! str_eq( cur_fullname, sharp_file->full_fname) ? " 1" : null);
+ /* Suffix " 1" for the file specified by -include */
+#endif
+}
+
+static char * set_files(
+ int argc,
+ char ** argv,
+ const char ** in_pp,
+ const char ** out_pp
+ )
+/*
+ * Set input and/or output files.
+ */
+{
+ char * cp;
+
+ if (*in_pp == 0) { /* Input file */
+ cp = argv[ mcpp_optind++];
+#if SYS_FAMILY == SYS_WIN
+ cp = bsl2sl( cp);
+#endif
+ *in_pp = cp;
+ }
+ if (mcpp_optind < argc && argv[ mcpp_optind][ 0] != '-'
+ && *out_pp == 0) {
+ cp = argv[ mcpp_optind++];
+#if SYS_FAMILY == SYS_WIN
+ cp = bsl2sl( cp);
+#endif
+ *out_pp = cp; /* Output file */
+ }
+ if (mcpp_optind >= argc)
+ return 0; /* Exhausted command line arguments */
+ if (argv[ mcpp_optind][ 0] == '-')
+ return argv[ mcpp_optind]; /* More options */
+ cfatal( "Excessive file argument \"%s\"", argv[ mcpp_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.
+ * 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).
+ * Ignore non-existent directory.
+ * Note that this routine should be called only in initializing steps,
+ * because increase of include dirs causes reallocation of incdir[].
+ * Note: a trailing PATH-DELIM is appended by norm_path().
+ */
+{
+ char * norm_name;
+ const char ** ip;
+
+ if (incdir == 0) { /* Should be initialized */
+ max_inc = INIT_NUM_INCLUDE;
+ incdir = (const char **) ACE_OS::malloc( sizeof (char *) * max_inc);
+ incend = &incdir[ 0];
+ } else if (incend - incdir >= max_inc) { /* Buffer full */
+#if SYSTEM == SYS_MAC
+ size_t framework_pos = to_search_framework - incdir;
+#endif
+#if COMPILER == GNUC
+ size_t sys_pos = 0;
+ if (sys_dirp)
+ sys_pos = sys_dirp - incdir;
+#endif
+ incdir = (const char **) ACE_OS::realloc( reinterpret_cast <char *> (incdir), sizeof (char *) * max_inc * 2);
+ incend = &incdir[ max_inc];
+#if COMPILER == GNUC
+ if (sys_pos)
+ sys_dirp = &incdir[ sys_pos];
+#endif
+#if SYSTEM == SYS_MAC
+ to_search_framework = &incdir[ framework_pos];
+#endif
+ max_inc *= 2;
+ }
+
+ if (dirname == 0)
+ return; /* Only to initialize incdir[] */
+ norm_name = norm_dir( dirname, FALSE);
+ if (! norm_name) /* Non-existent */
+ return;
+ for (ip = incdir; ip < incend; ip++) {
+ if (str_case_eq( *ip, norm_name)) {
+ if (option_flags.v && ! (mcpp_debug & MACRO_CALL))
+ mcpp_fprintf( ERR, "Duplicate directory \"%s\" is ignored\n"
+ , norm_name);
+ ACE_OS::free( norm_name); /* Already registered */
+ return;
+ }
+ }
+ /* Register new directory */
+ *incend++ = norm_name;
+}
+
+#if SYSTEM == SYS_MAC && COMPILER == GNUC
+/* Definitions for "header map" file of Xcode / Apple-GCC. */
+/* These definitions were taken from cpplib.h of Apple-GCC-4.0.1 */
+
+#define HMAP_SAME_ENDIANNESS_MAGIC \
+ (((((('h' << 8) | 'm') << 8) | 'a') << 8) | 'p')
+
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+
+struct hmap_bucket
+{
+ uint32 key; /* Offset (into strings) of key */
+ struct {
+ uint32 prefix; /* Offset (into strings) of value prefix */
+ uint32 suffix; /* Offset (into strings) of value suffix */
+ } value; /* Value (prefix- and suffix-strings) */
+};
+
+struct hmap_header_map
+{
+ uint32 magic; /* Magic word, also indicates byte order */
+ uint16 version; /* Version number -- currently 1 */
+ uint16 _reserved; /* Reserved for future use -- zero for now */
+ uint32 strings_offset; /* Offset to start of string pool */
+ uint32 count; /* Number of entries in the string table */
+ uint32 capacity; /* Number of buckets (always a power of 2) */
+ uint32 max_value_length;
+ /* Length of longest result path (excl. '\0') */
+ struct hmap_bucket buckets[1];
+ /* Inline array of 'capacity' maptable buckets */
+ /* Strings follow the buckets, at strings_offset. */
+};
+#endif
+
+static char * norm_dir(
+ const char * dirname, /* Directory path to normalize */
+ int /*framework*/ /* Setting a framework directory*/
+ )
+/*
+ * Normalize include directory path.
+ * Handle -isysroot option for GCC, including framework directory for SYS_MAC.
+ */
+{
+ char * norm_name;
+
+#if COMPILER == GNUC
+ if (sysroot && sys_dirp) {
+ /* Logical system root specified and dirname is system header dir */
+ char delim[ 2] = { EOS, EOS};
+ char * dir;
+#if SYSTEM == SYS_MAC
+ if (! framework && memcmp( dirname, "/usr/", 5) != 0)
+ return 0; /* /Developer/usr/lib/gcc/ */
+#endif
+ if (dirname[ 0] != PATH_DELIM)
+ delim[ 0] = PATH_DELIM;
+ dir = ACE_OS::malloc( ACE_OS::strlen( sysroot) + ACE_OS::strlen( dirname) + 2);
+ ACE_OS::sprintf( dir, "%s%s%s", sysroot, delim, dirname);
+ dirname = dir;
+ }
+#endif
+#if SYSTEM == SYS_MAC && COMPILER == GNUC
+ if (ACE_OS::strlen( dirname) > 5
+ && str_case_eq( dirname + ACE_OS::strlen( dirname) - 5, ".hmap")) {
+ /* "header map" file (not an include directory) */
+ norm_name = norm_path( null, dirname, FALSE, TRUE);
+ if (! norm_name && option_flags.v)
+ mcpp_fprintf( ERR, "Invalid header map file \"%s\" is ignored\n"
+ , dirname);
+ } else
+#endif
+ {
+ norm_name = norm_path( dirname, 0, FALSE, FALSE);
+ /* Normalize the pathname to compare */
+ if (! norm_name && option_flags.v && ! (mcpp_debug & MACRO_CALL))
+ mcpp_fprintf( ERR, "Non-existent directory \"%s\" is ignored\n"
+ , dirname);
+ }
+#if COMPILER == GNUC
+ if (sysroot && sys_dirp)
+ ACE_OS::free( dirname);
+#endif
+
+ return norm_name;
+}
+
+static char * norm_path(
+ const char * dir, /* Include directory (maybe "", never 0) */
+ const char * fname,
+ /* Filename (possibly has directory part, or maybe 0) */
+ int inf, /* If TRUE, output some infs when (mcpp_debug & PATH) */
+ int /*hmap*/ /* "header map" file of Apple-GCC */
+ )
+/*
+ * 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.
+ * Return a malloc'ed buffer, if the directory/file exists.
+ * Return 0, if the specified directory/file does not exist or 'dir' is
+ * not a directory or 'fname' is not a regular file.
+ * This routine is called from set_a_dir(), init_gcc_macro(), do_once() and
+ * open_file().
+ */
+{
+ char * norm_name; /* The path-list converted */
+ char * start;
+ char * cp1;
+ char * cp2;
+ char * abs_path;
+ int len; /* Should not be size_t */
+ size_t start_pos = 0;
+ char slbuf1[ PATHMAX+1]; /* Working buffer */
+#if SYS_FAMILY == SYS_UNIX
+ char slbuf2[ PATHMAX+1]; /* Working buffer for dereferencing */
+#endif
+#if SYSTEM == SYS_CYGWIN || SYSTEM == SYS_MINGW
+ static char * root_dir;
+ /* System's root directory in Windows file system */
+ static size_t root_dir_len;
+#if SYSTEM == SYS_CYGWIN
+ static char * cygdrive = "/cygdrive/"; /* Prefix for drive letter */
+#else
+ static char * mingw_dir; /* "/mingw" dir in Windows */
+ static size_t mingw_dir_len;
+#endif
+#endif
+#if HOST_COMPILER == MSC
+ struct _stat st_buf;
+#else
+ ACE_stat st_buf;
+#endif
+
+ if (! dir || (*dir && is_full_path( fname)))
+ cfatal( "Bug: Wrong argument to norm_path()" /* _F_ */
+ , 0, 0L, 0);
+ inf = inf && (mcpp_debug & PATH); /* Output information */
+
+ ACE_OS::strcpy( slbuf1, dir); /* Include directory */
+ len = ACE_OS::strlen( slbuf1);
+ if (fname && len && slbuf1[ len - 1] != PATH_DELIM) {
+ slbuf1[ len] = PATH_DELIM; /* Append PATH_DELIM */
+ slbuf1[ ++len] = EOS;
+ } else if (! fname && len && slbuf1[ len - 1] == PATH_DELIM) {
+ /* stat() of some systems do not like trailing '/' */
+ slbuf1[ --len] = EOS;
+ }
+ if (fname)
+ ACE_OS::strcat( slbuf1, fname);
+ if (ACE_OS::stat( slbuf1, & st_buf) != 0 /* Non-existent */
+ || (! fname && ! S_ISDIR( st_buf.st_mode))
+ /* Not a directory though 'fname' is not specified */
+ || (fname && ! S_ISREG( st_buf.st_mode)))
+ /* Not a regular file though 'fname' is specified */
+ return 0;
+#if SYSTEM == SYS_MAC && COMPILER == GNUC
+ if (hmap) { /* Dirty "header map" file */
+ struct hmap_header_map hmap;
+ size_t cnt;
+ FILE * fp;
+ fp = fopen( fname, "r");
+ cnt = fread( & hmap, sizeof (struct hmap_header_map), 1, fp);
+ fclose( fp);
+ if (cnt == 0 || hmap.magic != HMAP_SAME_ENDIANNESS_MAGIC)
+ return 0;
+ }
+#endif
+ if (! fname) {
+ slbuf1[ len] = PATH_DELIM; /* Append PATH_DELIM */
+ slbuf1[ ++len] = EOS;
+ }
+#if SYS_FAMILY == SYS_UNIX
+ /* Dereference symbolic linked directory or file, if any */
+ slbuf1[ len] = EOS; /* Truncate PATH_DELIM and 'fname' part, if any */
+ slbuf2[ 0] = EOS;
+ if (*dir && ! fname) { /* Registering include directory */
+ /* Symbolic link check of directories are required */
+ deref_syml( slbuf1, slbuf2, slbuf1);
+ } else if (fname) { /* Regular file */
+ 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, PATHMAX)) > 0) {
+ /* Dereference symbolic linked file (not directory) */
+ *(slbuf2 + len) = EOS;
+ cp1 = slbuf1;
+ if (slbuf2[ 0] != PATH_DELIM) { /* Relative path */
+ cp2 = ACE_OS::strrchr( slbuf1, PATH_DELIM);
+ if (cp2) /* Append to the source directory */
+ cp1 = cp2 + 1;
+ }
+ ACE_OS::strcpy( cp1, slbuf2);
+ }
+ }
+ if (inf) {
+ if (slbuf2[ 0])
+ mcpp_fprintf( DBG, "Dereferenced \"%s%s\" to \"%s\"\n"
+ , dir, fname ? fname : null, slbuf1);
+ }
+#endif
+ len = ACE_OS::strlen( slbuf1);
+ start = norm_name = (char *)ACE_OS::malloc( len + 1); /* Need a new buffer */
+ ACE_OS::strcpy( norm_name, slbuf1);
+#if SYS_FAMILY == SYS_WIN
+ bsl2sl( norm_name);
+#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 (len >= 8 && (memcmp( cp1, "/usr/bin", 8) == 0
+ || memcmp( cp1, "/usr/lib", 8) == 0)) {
+ memmove( cp1, cp1 + 4, len - 4 + 1); /* Remove "/usr" */
+ len -= 4;
+ }
+ if (*cp1 == '/' && (len < 10 || 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 = ACE_OS::malloc( ACE_OS::strlen( CYGWIN_ROOT_DIRECTORY) + 1);
+ ACE_OS::strcpy( root_dir, CYGWIN_ROOT_DIRECTORY);
+ *(root_dir + 1) = *root_dir; /* "x:/" to " x/" */
+ cp1 = ACE_OS::malloc( 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 = ACE_OS::malloc( 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 && isalpha( *(cp1 + 1))
+ && *(cp1 + 2) == PATH_DELIM) { /* /c/, /d/, etc*/
+ *cp1 = *(cp1 + 1);
+ *(cp1 + 1) = ':'; /* Convert to c:/, d:/, etc */
+ } else if (memcmp( cp1, "/mingw", 6) == 0) {
+ if (! mingw_dir_len) { /* Should be initialized */
+ mingw_dir_len = ACE_OS::strlen( MINGW_DIRECTORY);
+ mingw_dir = ACE_OS::malloc( mingw_dir_len + 1);
+ ACE_OS::strcpy( mingw_dir, MINGW_DIRECTORY);
+ }
+ cp1 = ACE_OS::malloc( mingw_dir_len + len + 1);
+ 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 (memcmp( cp1, "/usr", 4) == 0) {
+ 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 = ACE_OS::malloc( root_dir_len + 1);
+ ACE_OS::strcpy( root_dir, MSYS_ROOT_DIRECTORY);
+ }
+ cp1 = ACE_OS::malloc( 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; /* Next to 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 = (char *)ACE_OS::malloc( len + ACE_OS::strlen( cur_work_dir) + 1);
+ cp1 = mcpp_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 (inf) {
+ char debug_buf[ PATHMAX+1];
+ ACE_OS::strcpy( debug_buf, dir);
+ ACE_OS::strcat( debug_buf, fname ? fname : null);
+#if SYS_FAMILY == SYS_WIN
+ bsl2sl( debug_buf);
+#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, /* Original path-list */
+ char * slbuf2, /* Working buffer */
+ char * chk_start /* Pointer into slbuf1 */
+ )
+/* 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, PATHMAX)) > 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
+
+#if COMPILER == GNUC
+
+static void init_gcc_macro( void)
+/*
+ * Predefine GCC macros.
+ * This routine should be called after opening output file in order to putout
+ * macro informations by -K option into the file.
+ * Also this routine should be called before undef_macros() in order to
+ * permit undefining a macro by -U option.
+ */
+{
+ char fname[ BUFSIZ];
+ char lbuf[ BUFSIZ];
+ char * include_dir; /* The version-specific include directory */
+ char * tmp;
+ FILE * fp;
+ DEFBUF * defp;
+ const char * cp;
+ char * tp;
+ int i;
+
+ if (nflag) /* -undef option */
+ goto undef_special;
+
+ tmp = ACE_OS::malloc( ACE_OS::strlen( INC_DIR) + ACE_OS::strlen( "/mingw/mcpp-gcc-")
+ + ACE_OS::strlen( arch) + 1);
+#if SYSTEM == SYS_CYGWIN
+ if (no_cygwin) {
+ ACE_OS::sprintf( tmp, "%s/mingw/mcpp-gcc-%s", INC_DIR, arch);
+ } else {
+ ACE_OS::sprintf( tmp, "%s/mcpp-gcc-%s", INC_DIR, arch);
+ }
+#else
+ ACE_OS::sprintf( tmp, "%s/mcpp-gcc-%s", INC_DIR, arch);
+#endif
+ include_dir = norm_path( tmp, 0, TRUE, FALSE);
+ ACE_OS::free( tmp);
+
+ for (i = 0; i <= 1; i++) {
+ int nargs;
+
+ if ((mcpp_mode == POST_STD || ansi) && i == 0)
+ continue; /* POST_STD or __STRICT_ANSI__ does not */
+ /* predefine non-conforming macros */
+ /* The predefined macro file */
+ cp = i ? "std" : "old";
+ ACE_OS::sprintf( fname, "%sg%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 = fopen( fname, "r")) == 0) {
+ mcpp_fprintf( ERR, "The mode for %s has not been installed.\n"
+ , arch);
+ longjmp( error_exit, -1);
+ }
+ nargs = i ? 0 : DEF_NOARGS_PREDEF_OLD;
+ /* g*_predef_std.h has DEF_NOARGS_PREDEF or non-negative args */
+ /* while g*_predef_old.h has only DEF_NOARGS_PREDEF_OLD args */
+ while (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, nargs); /* Ignore re-definition */
+ }
+ skip_nl();
+ }
+ }
+ ACE_OS::free( include_dir);
+
+ undef_special:
+ if (look_id( "__OPTIMIZE__")) /* -O option is specified */
+ undefine( "__NO_INLINE__");
+}
+
+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::strchr( env, ' ')) != 0) {
+ *cp++ = EOS;
+ while (*cp == ' ')
+ cp++;
+ }
+ if (! mkdep_fp) /* Command line option precedes */
+ mkdep_fp = fopen( env, "a");
+ if (! mkdep_target)
+ mkdep_target = cp;
+}
+
+#elif COMPILER == MSC
+
+static void init_msc_macro( void)
+/*
+ * Define a few MSC-specific predefined macros.
+ */
+{
+ DEFBUF * defp;
+ int i;
+
+ defp = look_id( "_MSC_VER");
+ i = atoi( defp->repl);
+ if (i >= 1400) { /* _MSC_VER >= 1400 */
+ look_and_install( "_MT", DEF_NOARGS_PREDEF, null, "1");
+ if (cplus_val && ! wchar_t_modified) {
+ /* -Zc:wchar_t- was not specified */
+ look_and_install( "_NATIVE_WCHAR_T_DEFINED", DEF_NOARGS_PREDEF
+ , null, "1");
+ look_and_install( "_WCHAR_T_DEFINED", DEF_NOARGS_PREDEF, null
+ , "1");
+ }
+ }
+}
+
+#endif
+
+static void def_macros( void)
+/*
+ * Define macros specified by -D option.
+ * This routine should be called before undef_macros().
+ */
+{
+ size_t i(0);
+
+ for (i = 0; i < def_cnt; i++)
+ {
+ def_a_macro( 'D', def_list[ i]);
+ }
+
+}
+
+static void undef_macros( void)
+/*
+ * Undefine macros specified by -U option.
+ * This routine should be called after init_predefine().
+ */
+{
+ const char * name;
+ size_t i;
+
+ for (i = 0; i < undef_cnt; i++) {
+ name = undef_list[ i];
+ if (look_id( name) != 0)
+ undefine( name);
+ else if (warn_level & 8)
+ mcpp_fprintf( ERR, "\"%s\" wasn't defined\n", name);
+ }
+}
+
+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_INITLEN (MKDEP_INIT * 0x100)
+#define MKDEP_MAX (MKDEP_INIT * 0x10)
+#define MKDEP_MAXLEN (MKDEP_INITLEN * 0x10)
+
+ static char * output = 0; /* File names */
+ static size_t * pos = 0; /* Offset to filenames */
+ static unsigned int pos_num; /* Index of pos[] */
+ static char * out_p; /* Pointer to output[] */
+ static size_t mkdep_len; /* Size of output[] */
+ static size_t pos_max; /* Size of pos[] */
+ static FILE * fp; /* Path to output dependency line */
+ static size_t llen; /* Length of current physical output line */
+ size_t * pos_p; /* Index into pos[] */
+ size_t fnamlen; /* Length of filename */
+
+ if (fp == 0) { /* Main source file. Have to initialize. */
+#ifdef MCPP_LIB
+ if (output != 0) {
+ ACE_OS::free( output);
+ ACE_OS::free( pos);
+ }
+#endif
+ output = (char *) ACE_OS::malloc( mkdep_len = MKDEP_INITLEN);
+ pos = (size_t *) ACE_OS::malloc( (pos_max = MKDEP_INIT) * sizeof (size_t));
+ 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 = mcpp_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" /* _E_ */
+ , 0, 0L, 0);
+ if (fp == fp_out)
+ mcpp_fputs( output, OUT);
+ else
+ ACE_OS::fputs( output, fp);
+ return;
+ } else if (ACE_OS::strlen( output) * 2 + (pos_num * 2) >= mkdep_len) {
+ /* Enlarge the buffer */
+ size_t len = out_p - output;
+ output = (char *) ACE_OS::realloc( output, mkdep_len *= 2);
+ out_p = output + len;
+ }
+ pos_num--;
+ for (pos_p = &pos[ 0]; pos_p <= &pos[ pos_num]; pos_p++) {
+ if (pos_p == &pos[ pos_num]) { /* End of output */
+ for (cp = output + *pos_p; *cp != '\n'; cp++)
+ ;
+ c = '\n'; /* Append newline */
+ } else {
+ cp = output + *(pos_p + 1) - 1;
+ while( *cp == ' ' || *cp == '\\' || *cp == '\n')
+ cp--; /* Remove trailing spaces */
+ c = *(++cp);
+ }
+ *cp = EOS;
+ out_p = mcpp_stpcpy( out_p, output + *pos_p);
+ out_p = mcpp_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);
+ ACE_OS::fclose( fp);
+ }
+ fp = 0; /* Clear for the next call in MCPP_LIB build */
+ return;
+ }
+
+ fnamlen = ACE_OS::strlen( filename);
+ /* Check the recorded filename */
+ for (pos_p = pos; pos_p < &pos[ pos_num]; pos_p++) {
+ if (ACE_OS::memcmp( output + *pos_p, 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 = mcpp_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);
+ /* Need to enlarge the buffer */
+ if (pos_num >= pos_max) {
+ pos = (size_t *) ACE_OS::realloc( (char *) pos
+ , (pos_max *= 2) * sizeof (size_t *));
+ }
+ if (output + mkdep_len <= out_p + fnamlen + 1) {
+ size_t len = out_p - output;
+ output = (char *) ACE_OS::realloc( output, mkdep_len *= 2);
+ out_p = output + len;
+ }
+ *out_p++ = ' ';
+ pos[ pos_num++] = out_p - output; /* Remember the offset */
+ /* Don't use pointer, since 'output' may be reallocated later. */
+ out_p = mcpp_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[ PATHMAX];
+ 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 = mcpp_stpcpy( output, mkdep_target);
+ }
+ } else {
+ ACE_OS::strcpy( cp, OBJEXT);
+ out_p = mcpp_stpcpy( output, prefix);
+ }
+
+ *out_p++ = ':';
+ *out_p = EOS;
+ return out_p;
+}
+
+static char * md_quote(
+ char * output
+ )
+/*
+ * 'Quote' $, tab and space.
+ * This function was written 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[ PATHMAX + 16];
+ int token_type;
+ char * fname;
+ char * filename;
+ 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 macro */
+ int c;
+ char *hp;
+
+ hp = header;
+ *hp = EOS;
+ c = delim;
+ while (get_unexpandable( c, FALSE) != NO_TOKEN) {
+ /* Expand any macros in the line */
+ if (header + PATHMAX < hp + (int) (workp - work_buf))
+ cfatal( toolong_fname, header, 0L, work_buf);
+ hp = mcpp_stpcpy( hp, work_buf);
+ while (char_type[ c = get_ch()] & HSP)
+ *hp++ = c;
+ }
+ *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 + PATHMAX);
+ 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 + PATHMAX, 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 SYS_FAMILY == SYS_WIN
+ bsl2sl( fname);
+#endif
+ filename = fname;
+#if NO_DIR /* Unofficial feature */
+ if (no_dir) { /* Strip directory components */
+ char src_dir[ PATHMAX] = { EOS, };
+ if (has_directory( fname, src_dir))
+ filename = fname + ACE_OS::strlen( src_dir);
+ delim = '"'; /* Even a system header is handled as a local one */
+ }
+#endif
+ if (open_include( filename, (delim == '"'), next)) {
+ /* 'fname' should not be ACE_OS::free()ed, it is used as file-> */
+ /* real_fname and has been registered into fnamelist[] */
+ return TRUE;
+ }
+
+ cerror( "Can't open include file \"%s\"", filename, 0L, 0); /* _E_ */
+ error:
+ ACE_OS::free( fname);
+ return FALSE;
+
+ not_header:
+ cerror( "Not a header name \"%s\"", fname, 0L, 0); /* _E_ */
+ syntax_error:
+ skip_nl();
+ return FALSE;
+}
+
+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.
+ * 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 it fails.
+ */
+{
+ char src_dir[ PATHMAX] = { EOS, }; /* Directory part of includer */
+ int full_path; /* Filename is full-path-list */
+ int has_dir = FALSE; /* Includer has directory part */
+ int has_dir_src = FALSE;
+ int has_dir_fname = FALSE;
+
+ full_path = is_full_path( filename);
+
+ if (!full_path && searchlocal && (search_rule & SOURCE)) {
+ has_dir_src = has_directory( infile->src_dir, src_dir);
+ has_dir_fname = has_directory( infile->real_fname
+ , src_dir + ACE_OS::strlen( src_dir));
+ /* Get directory part of the parent file of the file to include.*/
+ /* Note that infile->dirp of main input file is set to "" and */
+ /* remains the same even if -include options are processed. */
+ has_dir = has_dir_src || has_dir_fname
+ || (**(infile->dirp) != EOS);
+ }
+ if (mcpp_debug & PATH)
+ mcpp_fprintf( DBG, "filename: %s\n", filename);
+
+#if COMPILER == GNUC
+ if (! full_path) {
+ if (i_split /* -I- option is specified */
+ || next) /* or #include_next */
+ goto search_dirs;
+ }
+#endif
+
+ 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, 0, filename, searchlocal && !full_path
+ , FALSE, FALSE))
+ 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".
+ */
+ if (open_file( infile->dirp, src_dir, filename, TRUE, FALSE, FALSE))
+ return TRUE;
+ }
+
+#if COMPILER == MSC
+ if (searchlocal) {
+ /* Visual C searches ancestor source's directory, too. */
+ FILEINFO * file = infile;
+ while ((file = file->parent) != 0) {
+ /* Search each parent includer's directory */
+ if (open_file( file->dirp, src_dir, filename, TRUE, FALSE, FALSE))
+ return TRUE;
+ }
+ }
+#endif
+#if COMPILER == GNUC
+ search_dirs:
+ if (searchlocal) {
+ /* Search the directories specified by -iquote option, if any. */
+ const char ** qdir;
+ for (qdir = quote_dir; qdir < quote_dir_end; qdir++) {
+ if (open_file( qdir, 0, filename, FALSE, FALSE, FALSE))
+ return TRUE;
+ }
+ }
+#endif
+ /* Search the include directories */
+ 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 (! source)
+ return FALSE;
+ if ((sp = ACE_OS::strrchr( source, PATH_DELIM)) == 0) {
+ return FALSE;
+ } else {
+ len = (size_t)(sp - source) + 1; /* With path-delimiter */
+ ACE_OS::memcpy( directory, source, len);
+ directory[ len] = EOS;
+ return TRUE;
+ }
+}
+
+static int is_full_path(
+ const char * path
+ )
+/*
+ * Check whether the path is a full (absolute) path list or not.
+ */
+{
+ if (! path)
+ return FALSE;
+#if SYS_FAMILY == SYS_UNIX
+ if (path[0] == PATH_DELIM)
+#elif SYS_FAMILY == SYS_WIN
+ if ((path[1] == ':' && path[2] == PATH_DELIM) /* "C:/path" */
+ || path[0] == PATH_DELIM) /* Root dir of current drive */
+#elif 1
+ /* For other systems you should write code here. */
+ if (path[0] == PATH_DELIM)
+#endif
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static int search_dir(
+ char * filename, /* File name to include */
+ int /*searchlocal*/, /* #include "header.h" */
+ int /*next*/ /* 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 */
+
+ incptr = incdir;
+#if COMPILER == GNUC
+ if (next && **inc_dirp != EOS)
+ incptr = inc_dirp + 1;
+ /* In case of include_next search after the includer's directory */
+#endif
+
+ for ( ; incptr < incend; incptr++) {
+ if (ACE_OS::strlen( *incptr) + ACE_OS::strlen( filename) >= PATHMAX)
+ cfatal( toolong_fname, *incptr, 0L, filename); /* _F_ */
+#if SYSTEM == SYS_MAC
+ if (incptr == to_search_framework && ! searchlocal) {
+ /* Now search the framework dirs */
+ if (search_framework( filename)) { /* Found */
+ if (in_import) /* "#import"ed file is once only */
+ do_once( infile->full_fname);
+ return TRUE;
+ }
+ /* Else continue to search incptr */
+ }
+#endif
+ if (open_file( incptr, 0, filename, FALSE, FALSE, FALSE))
+ /* Now infile has been renewed */
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int open_file(
+ const char ** dirp, /* Pointer to include directory */
+ const char * src_dir, /* Source directory of includer */
+ const char * filename, /* Filename (possibly has directory) */
+ int /*local*/, /* #include "file" */
+ int include_opt, /* Specified by -include option */
+ int /*sys_frame*/ /* System framework header (for SYS_MAC)*/
+ )
+/*
+ * 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().
+ */
+{
+ char dir_fname[ PATHMAX] = { EOS, };
+#if HOST_COMPILER == BORLANDC
+ /* Borland's ACE_OS::fopen() does not set errno. */
+ static int max_open = FOPEN_MAX - 5;
+#else
+ static int max_open;
+#endif
+ int len;
+ FILEINFO * file = infile;
+ FILE * fp;
+ char * fullname;
+ const char * fname;
+
+ errno = 0; /* Clear errno possibly set by path searching */
+#if SYSTEM == SYS_MAC && COMPILER == GNUC
+ if (ACE_OS::strlen( *dirp) > 5
+ && str_case_eq( *dirp + ACE_OS::strlen( *dirp) - 5, ".hmap")) {
+ /* Search header map file for a header */
+ if (! search_header_map( *dirp, filename, dir_fname))
+ return 0;
+ fname = dir_fname; /* Found a path-list */
+ dirp = &null;
+ goto search;
+ } else
+#endif
+ {
+ if (mcpp_debug & PATH)
+ mcpp_fprintf( DBG, "Searching %s%s%s\n", *dirp
+ , src_dir ? src_dir : null, filename);
+ }
+ /* src_dir is usually 0. This is specified to */
+ /* search the source directory of the includer. */
+ if (src_dir && *src_dir != EOS) {
+ ACE_OS::strcpy( dir_fname, src_dir);
+ ACE_OS::strcat( dir_fname, filename);
+ fname = dir_fname;
+ } else {
+ fname = filename;
+ }
+ //search:
+ fullname = norm_path( *dirp, fname, TRUE, FALSE);
+ /* Convert to absolute path */
+ if (! fullname) /* Non-existent or directory */
+ return FALSE;
+ if (standard && included( fullname)) /* Once included */
+ goto true_label;
+
+ 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 */
+ if (mcpp_debug & PATH) {
+#if HOST_COMPILER == BORLANDC
+ if (include_nest == FOPEN_MAX - 5)
+#else
+ if (max_open == 0)
+#endif
+ mcpp_fprintf( DBG,
+ "#include nest reached at the maximum of system: %d, returned errno: %d\n"
+ , include_nest, errno);
+ }
+ /*
+ * 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);
+ goto false_label;
+ }
+ if (max_open == 0) /* Remember the limit of the system */
+ max_open = include_nest;
+ } else if (fp == 0) /* No read permission */
+ goto false_label;
+ /* Truncate buffer of the includer to save memory */
+ len = (int) (file->bptr - file->buffer);
+ if (len) {
+ file->buffer = (char *) ACE_OS::realloc( file->buffer, len + 1);
+ file->bptr = file->buffer + len;
+ }
+
+ if (! include_opt)
+ sharp( 0, 0); /* Print includer's line num and fname */
+ add_file( fp, src_dir, filename, fullname, include_opt);
+ /* Add file-info to the linked list. 'infile' has been just renewed */
+ /*
+ * 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;
+#if 0 /* This part is only for debugging */
+ chk_dirp( dirp);
+#endif
+#if COMPILER == GNUC
+ if ((**dirp != EOS && sys_dirp <= dirp && dirp <= incend)
+#if SYSTEM == SYS_MAC
+ || sys_frame
+#endif
+ )
+ infile->sys_header = TRUE; /* Found in a system header dir */
+ else
+ infile->sys_header = FALSE;
+#endif
+ cur_fullname = fullname;
+
+ if (option_flags.z) {
+ no_output++; /* Don't output the included file */
+ if (include_nest == 2)
+ mcpp_fprintf( OUT, "#include \"%s\"\n", fullname);
+ /* Output #include line instead, if it is in main source file */
+ } else if (! include_opt) { /* Do not sharp() on -include */
+ src_line = 1; /* Working on line 1 now */
+ sharp( 0, 1); /* Print out the included file name */
+ }
+ src_line = 0; /* To read the first line */
+
+ if (mkdep && ((mkdep & MD_SYSHEADER) || ! infile->sys_header))
+ put_depend( fullname); /* Output dependency line */
+
+ true_label:
+ return TRUE;
+ false_label:
+ ACE_OS::free( fullname);
+ return FALSE;
+}
+
+void add_file(
+ FILE * fp, /* Open file pointer */
+ const char * ,/*src_dir*/ /* Directory of source */
+ const char * filename, /* Name of the file */
+ const char * fullname, /* Full path list */
+ int include_opt /* File specified by -include option */
+ )
+/*
+ * 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[] */
+ fullname = set_fname( fullname); /* Search or append to fnamelist[] */
+ file = get_file( filename, 0 /*src_dir*/, fullname, (size_t) NBUFF, include_opt);
+
+ /* file == infile */
+ file->fp = fp; /* Better remember FILE * */
+ cur_fname = fullname;
+
+ 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 == std_limits.inc_nest + 1)
+ cwarn( too_many_include_nest, 0, (long) std_limits.inc_nest, 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.
+ * file->real_fname and file->full_fname points into fnamelist[].
+ */
+{
+ INC_LIST * fnamep;
+ size_t fnamelen;
+
+ if (fnamelist == 0) { /* Should be initialized */
+ max_fnamelist = INIT_NUM_FNAMELIST;
+ fnamelist = (INC_LIST *) ACE_OS::malloc( sizeof (INC_LIST) * max_fnamelist);
+ fname_end = &fnamelist[ 0];
+ } else if (fname_end - fnamelist >= max_fnamelist) {
+ /* Buffer full: double the elements */
+ fnamelist = (INC_LIST *) ACE_OS::realloc( reinterpret_cast<char *> (fnamelist), sizeof (INC_LIST) * max_fnamelist * 2);
+ fname_end = &fnamelist[ max_fnamelist];
+ max_fnamelist *= 2;
+ }
+
+ /* Register the filename in fnamelist[] */
+ fnamelen = ACE_OS::strlen( filename);
+ for (fnamep = fnamelist; fnamep < fname_end; fnamep++) {
+ if (fnamep->len == fnamelen && str_case_eq( fnamep->name, filename))
+ {
+ return filename; /* Already registered */
+ }
+ }
+ fname_end->name = (char *) ACE_OS::malloc( fnamelen + 1);
+ filename = ACE_OS::strcpy( fname_end->name, filename);
+ /* Global pointer for get_file() */
+ fname_end->len = fnamelen;
+ fname_end++;
+
+ return filename;
+}
+
+#if SYSTEM == SYS_MAC
+#if COMPILER == GNUC
+
+/* Routines to search "header map" file of Xcode / Apple-GCC. */
+/* search_header_map() and hmap_hash() were written referring to */
+/* c-incpath.c of Apple-GCC-4.0.1. */
+
+static char * search_header_map(
+ const char * hmap_file, /* Header map file */
+ const char * filename, /* Filename to search */
+ char * pathlist /* Buffer for a found pathlist */
+ )
+/*
+ * Search a table in "header map" file for a header.
+ */
+{
+ struct stat stat_buf;
+ FILE * fp;
+ size_t fsize;
+ const char * contents;
+ struct hmap_header_map * hmap;
+ struct hmap_bucket * buckets;
+ const char * strings;
+ uint32 mask;
+ uint32 key_offs;
+ uint32 i;
+
+ stat( hmap_file, &stat_buf); /* Get size of the file */
+ fsize = stat_buf.st_size;
+ contents = ACE_OS::malloc( fsize + 1);
+ fp = ACE_OS::fopen( hmap_file, "r");
+ fread( contents, fsize, 1, fp); /* Read whole of the file at once */
+ hmap = (struct hmap_header_map *) contents;
+
+ strings = ((const char *) hmap) + hmap->strings_offset;
+ buckets = hmap->buckets;
+ mask = hmap->capacity - 1;
+ i = hmap_hash( filename) & mask;
+ while ((key_offs = buckets[ i].key) != 0) {
+ if (str_case_eq( filename, strings + key_offs)) {
+ /* The names match. Make path-list. */
+ char * cp = mcpp_stpcpy( pathlist, strings + buckets[ i].value.prefix);
+ ACE_OS::strcpy( cp, strings + buckets[ i].value.suffix);
+ break;
+ }
+ i = ++i & mask;
+ }
+ ACE_OS::free( contents);
+ return key_offs ? pathlist : 0;
+}
+
+static unsigned hmap_hash(
+ const char * fname /* header name */
+ )
+/*
+ * Get hash value for the fname.
+ */
+{
+ const char * sp;
+ unsigned hash_code = 0;
+
+ for (sp = fname; *sp; sp++)
+ hash_code += tolower( *sp & 0xFF) * 13;
+ return hash_code;
+}
+#endif /* COMPILER == GNUC */
+
+static void init_framework( void)
+/*
+ * Initialize framework[].
+ */
+{
+ char * framework_dir;
+ /* Some frameworks may have been already specified by -F option. */
+ sys_framework = num_framework; /* These are system frameworks */
+#ifdef FRAMEWORK1
+ framework_dir = norm_dir( FRAMEWORK1, TRUE);
+ if (framework_dir)
+ framework[ num_framework++] = framework_dir;
+#endif
+#ifdef FRAMEWORK2
+ framework_dir = norm_dir( FRAMEWORK2, TRUE);
+ if (framework_dir)
+ framework[ num_framework++] = framework_dir;
+#endif
+#ifdef FRAMEWORK3
+ framework_dir = norm_dir( FRAMEWORK3, TRUE);
+ if (framework_dir)
+ framework[ num_framework++] = framework_dir;
+#endif
+ if (num_framework >= MAX_FRAMEWORK) {
+ mcpp_fputs( "Too many Framework directories.", ERR);
+ longjmp( error_exit, -1);
+ }
+}
+
+static const char * dot_frame = ".framework";
+
+static int search_framework(
+ char * filename
+ )
+/*
+ * Search "Framework" directories.
+ * 'frame/header.h' is converted to
+ * '/System/Library/Frameworks/frame.framework/Headers/header.h',
+ * '/System/Library/Frameworks/frame.framework/PrivateHeaders/header.h',
+ * and so on.
+ */
+{
+ char fullname[ PATHMAX + 1];
+ FILEINFO * file;
+ char * frame, * fname, * cp1, * cp2;
+ int sys_frame = FALSE;
+ int i;
+
+ cp1 = cp2 = ACE_OS::strchr( filename, PATH_DELIM);
+ /*
+ * 'filename' should be <frame/header> format or sometimes
+ * <frame/dir/header>.
+ * e.g.: <Foundation/Foundation.h>, <CarbonCore/OSUtils.h>
+ * or <IOKit/pwr_mgt/IOPMLib.h>.
+ */
+ if (! cp1)
+ return FALSE;
+ *cp1 = EOS;
+ frame = filename;
+ fname = cp1 + 1;
+
+ /* Search framework[] directories */
+ for (i = 0; i < num_framework; i++) {
+ cp1 = mcpp_stpcpy( fullname, framework[ i]);
+ /* 'fullname' e.g.: /System/Library/Frameworks/ */
+ if (search_subdir( fullname, cp1, frame, fname, sys_framework <= i))
+ return TRUE;
+ }
+
+ /*
+ * Search subframework dirs searching its possible parent framework
+ * starting from current file's directory to its ancestors.
+ * Header file in subframework directories should be included only
+ * by its parent or sibling framework headers.
+ */
+ for (i = sys_framework; i < num_framework; i++) {
+ size_t frame_len, fname_len;
+ frame_len = ACE_OS::strlen( framework[ i]);
+ fname_len = ACE_OS::strlen( infile->real_fname);
+ if (fname_len <= frame_len)
+ continue;
+ if (ACE_OS::memcmp( framework[ i], infile->real_fname, frame_len) == 0) {
+ sys_frame = TRUE;
+ break;
+ }
+ }
+ for (file = infile; file; file = file->parent) {
+ const char * dot;
+ size_t len;
+
+ if (! file->fp)
+ continue;
+ dot = strstr( file->real_fname, dot_frame);
+ if (! dot)
+ continue;
+ len = dot - file->real_fname + ACE_OS::strlen( dot_frame) + 1;
+ ACE_OS::memcpy( fullname, file->real_fname, len);
+ cp1 = fullname + len;
+ cp1 = mcpp_stpcpy( cp1, "Frameworks/");
+ /* 'fullname' e.g.: */
+ /* /System/Library/Frameworks/Foundation.framework/Frameworks/ */
+ if (search_subdir( fullname, cp1, frame, fname, sys_frame))
+ return TRUE;
+ }
+
+ *cp2 = PATH_DELIM; /* Restore original include file format */
+
+ return FALSE;
+}
+
+static int search_subdir(
+ char * fullname, /* Buffer for path-list to open */
+ char * cp, /* Latter half of 'fullname' */
+ char * frame, /* 'frame' of <frame/header> */
+ char * fname, /* 'header' of <frame/header> */
+ /* or sometimes 'dir/header' of <frame/dir/header> */
+ int sys_frame /* System framework header ? */
+ )
+/*
+ * Make path-list and try to open.
+ */
+{
+ static const char * subdir[] = { "Headers", "PrivateHeaders", 0};
+ int j, n;
+
+ cp += ACE_OS::sprintf( cp, "%s%s%c", frame, dot_frame, PATH_DELIM);
+ for (j = 0; subdir[ j] != 0; j++) {
+ n = ACE_OS::sprintf( cp, "%s%c%s", subdir[ j], PATH_DELIM, fname);
+ /*
+ * 'fullname' is for example:
+ * /System/Library/Frameworks/Foundation.framework/Headers/
+ * Foundation.h,
+ * /System/Library/Frameworks/Foundation.framework/Frameworks/
+ * CarbonCore.framework/Headers/OSUtils.h,
+ * or /System/Library/Frameworks/IOKit.framework/Headers/
+ * pwr_mgt/IOPMLib.h.
+ * Pass this as one filename argument to open_file() rather than
+ * deviding to directory part and file part. The first argument to
+ * open_file() which is a pointer to the directory part is remembered
+ * by FILEINFO struct. But, 'fullname' is over-written each time,
+ * and the former path-list is lost soon. Therefore, it cannot be
+ * passed as the first argument. In addition, though the first
+ * argument to open_file() is needed for #include_next, this directive
+ * has no meaning in framework.
+ */
+ if ((cp - fullname) + n > PATHMAX)
+ cfatal( "Too long framework path", 0, 0L, 0); /* _F_ */
+ if (open_file( &null, 0, fullname, FALSE, FALSE, sys_frame))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#endif /* SYSTEM == SYS_MAC */
+
+#if 0 /* This part is only for debugging */
+static int chk_dirp(
+ const char ** dirp
+ )
+/*
+ * Check the validity of include directory specified for open_file().
+ * Called only from open_file().
+ */
+{
+ const char ** ip;
+
+ if (dirp == &null)
+ return TRUE;
+
+ for (ip = incdir; ip < incend; ip++)
+ if (dirp == ip)
+ break;
+ if (ip == incend) {
+#if COMPILER == MSC
+ FILEINFO * pfile = infile->parent;
+ if (pfile) {
+ while ((pfile = pfile->parent) != 0) {
+ /* Search each parent includer's directory */
+ if (dirp == pfile->dirp)
+ break;
+ }
+ }
+ if (! pfile)
+#endif
+#if COMPILER == GNUC
+ const char ** qdir;
+ for (qdir = quote_dir; qdir < quote_dir_end; qdir++) {
+ if (dirp == qdir)
+ break;
+ }
+ if (qdir == quote_dir_end)
+#endif
+ {
+ cfatal( "Bug: *dirp:%s is invalid", *dirp, 0L, 0);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+#endif
+
+void sharp(
+ FILEINFO * sharp_file,
+ int flag /* Flag to append to the line for GCC */
+ )
+/*
+ * Output a line number line.
+ * 'file' is 'sharp_file' if specified,
+ * else (i.e. 'sharp_file' is 0) 'infile'.
+ */
+{
+ static FILEINFO * sh_file;
+ static int sh_line;
+ FILEINFO * file;
+ int line;
+
+ file = sharp_file ? sharp_file : infile;
+ if (! file)
+ return;
+ while (! file->fp)
+ file = file->parent;
+ line = sharp_file ? sharp_file->line : src_line;
+ if (no_output || option_flags.p || file == 0
+ || (file == sh_file && line == sh_line))
+ goto sharp_exit;
+ sh_file = file;
+ sh_line = line;
+ if (keep_comments)
+ mcpp_fputc( '\n', OUT); /* Ensure to be on line top */
+ if (std_line_prefix)
+ mcpp_fprintf( OUT, "#line %ld", line);
+ else
+ mcpp_fprintf( OUT, "%s%ld", LINE_PREFIX, line);
+ cur_file( file, sharp_file, flag);
+ mcpp_fputc( '\n', OUT);
+ sharp_exit:
+ wrong_line = FALSE;
+}
+
+static void cur_file(
+ FILEINFO * file, /* infile or sharp_file */
+ FILEINFO * sharp_file, /* The 'file' or 0 */
+ int /*flag*/ /* Flag to append for GCC */
+ )
+/*
+ * Output current source file name and line number.
+ * Called only from sharp() above.
+ */
+{
+ const char * name;
+
+ if (mcpp_debug & MACRO_CALL) { /* In macro notification mode */
+ if (sharp_file) /* Main input file */
+ {
+ name = file->filename;
+ }
+ else
+ {/* Output full-path-list, normalized */
+ name = cur_fullname;
+ }
+ } else { /* Usually, the path not "normalized" */
+ if (sharp_file) { /* Main input file */
+ name = file->filename;
+ } else if (str_eq( file->filename, file->real_fname)) {
+ ACE_OS::sprintf( work_buf, "%s%s", "" /* *(file->dirp)*/, cur_fname);
+ name = work_buf;
+ } else { /* Changed by '#line fname' directive */
+ name = file->filename;
+ }
+ }
+ if (sharp_filename == 0 || ! str_eq( name, sharp_filename)) {
+ if (sharp_filename != 0)
+ ACE_OS::free( sharp_filename);
+ sharp_filename = save_string( name);
+ }
+ mcpp_fprintf( OUT, " \"%s\"", name);
+#if COMPILER == GNUC
+ if (! std_line_prefix) {
+ if (flag) {
+ mcpp_fputc( ' ', OUT);
+ mcpp_fputc( '0' + flag, OUT);
+ }
+ if (file->sys_header)
+ 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] & mbchk) { /* First byte of MBCHAR */
+ char tmp[ PATHMAX];
+ 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;
+ LINE_COL line_col = { 0L, 0};
+
+ bp = mp = ACE_OS::malloc( (size_t)(NMACWORK + IDMAX));
+ /* Buffer for macro expansion */
+ mp_end = mp + NMACWORK;
+ tp = mcpp_stpcpy( mp, identifier);
+ do { /* Expand all the macros in the line */
+ int has_pragma;
+ if (token_type == NAM && (defp = is_macro( &tp)) != 0) {
+ tp = expand_macro( defp, bp, mp_end, line_col, & has_pragma);
+ if (has_pragma)
+ cerror( "_Pragma operator found in #pragma line" /* _E_ */
+ , 0, 0L, 0);
+ 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->full_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( TRUE, FALSE); /* #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) {
+ if (str_eq( identifier, "poison")
+ || str_eq( identifier, "dependency")) {
+ if (warn_level & 2)
+ cwarn( "Skipped the #pragma line" /*_W2_ */
+ , 0, 0L, 0);
+ goto skip_nl;
+ } else if (str_eq( identifier, "system_header")) {
+ infile->sys_header = TRUE; /* Mark as a system header */
+ 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_PREDEF, 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( 0, 0); /* 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 * fullname /* Full-path-list of the header */
+ )
+ /*
+ * Process #pragma once so as not to re-include the file later.
+ * This directive has been imported from GCC V.1.* / cpp as an extension.
+ */
+ {
+ if (once_list == 0) { /* Should initialize */
+ max_once = INIT_NUM_ONCE;
+ once_list = (INC_LIST *) ACE_OS::malloc( sizeof (INC_LIST) * max_once);
+ once_end = &once_list[ 0];
+ } else if (once_end - once_list >= max_once) {
+ /* Double the elements */
+ once_list = (INC_LIST *) ACE_OS::realloc( reinterpret_cast <char *> (once_list), sizeof (INC_LIST) * max_once * 2);
+ once_end = &once_list[ max_once];
+ max_once *= 2;
+ }
+ once_end->name = const_cast <char *> (fullname);
+ once_end->len = ACE_OS::strlen( fullname);
+ once_end++;
+ }
+
+ static int included(
+ const char * fullname
+ )
+ /*
+ * Has the file been once included ?
+ * This routine is only called from open_file().
+ */
+ {
+ INC_LIST * inc;
+ size_t fnamelen;
+
+ if (once_list == 0) /* No once file registered */
+ return FALSE;
+ fnamelen = ACE_OS::strlen( fullname);
+ for (inc = once_list; inc < once_end; inc++) {
+ if (inc->len == fnamelen && str_case_eq( inc->name, fullname)) {
+ /* Already included */
+ if (mcpp_debug & PATH)
+ mcpp_fprintf( DBG, "Once included \"%s\"\n", fullname);
+ return TRUE;
+ }
+ }
+ 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 *) ACE_OS::malloc( 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_ */
+ // static const char * const ext
+ // = "%s is not allowed by Standard%.0ld%s"; /* _W2_ _W8_*/
+
+#if COMPILER == GNUC
+ if (str_eq( identifier, "include_next")) {
+ if ((compiling && (warn_level & 2))
+ || (! compiling && (warn_level & 8)))
+ cwarn( 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( 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 SYSTEM == SYS_MAC
+ if (str_eq( identifier, "import")) {
+ if ((compiling && (warn_level & 2))
+ || (! compiling && (warn_level & 8)))
+ cwarn( ext, "#import", 0L
+ , compiling ? 0 : " (in skipped block)");
+ if (! compiling)
+ return;
+ in_import = in_include = TRUE;
+ do_include( FALSE);
+ in_import = in_include = FALSE;
+ return;
+ }
+#endif
+
+ if (! standard && do_prestd_directive())
+ return;
+
+ if (compiling) {
+ if (option_flags.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( TRUE, FALSE); /* #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;
+ }
+ 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 = ACE_OS::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, 0);
+ 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 },
+ { "macro_call", MACRO_CALL }, /* Implemented only in STD mode */
+ { "if", IF },
+ { "expression", EXPRESSION },
+ { "getc", GETC },
+ { "memory", MEMORY },
+ { 0, 0 },
+ };
+ struct Debug_arg *argp;
+ int num = 0;
+ 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 if (num == MACRO_CALL)
+ option_flags.k = TRUE; /* This pragma needs this mode */
+ } else {
+ mcpp_debug &= ~num;
+ }
+ }
+ c = skip_ws();
+ }
+ if ((mcpp_mode != STD && (mcpp_debug & MACRO_CALL)) || c != '\n') {
+ if (warn_level & 1) {
+ if (c != '\n') {
+ cwarn( not_ident, work_buf, 0L, 0);
+ } else {
+ cwarn( unknown_arg, work_buf, 0L, 0);
+ mcpp_debug &= ~num; /* Disable */
+ }
+ }
+ 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 = "./";
+ // int i;
+
+ 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);
+#if SYSTEM == SYS_MAC
+ mcpp_fputs( "Framework paths are as follows --\n", DBG);
+ for (i = 0; i < num_framework; i++ )
+ mcpp_fprintf( DBG, " %s\n", framework[ i]);
+ mcpp_fputs( "End of framework path list.\n", DBG);
+#endif
+ }
+
+ /*
+ * Note: The getopt() of glibc should not be used since the specification
+ * differs from the standard one.
+ * Use this mcpp_getopt() for mcpp.
+ */
+
+ /* Based on the public-domain-software released by AT&T in 1985. */
+
+#define OPTERR( s, c) if (mcpp_opterr) { \
+ mcpp_fputs( argv[0], ERR); \
+ mcpp_fputs( s, ERR); \
+ mcpp_fputc( c, ERR); \
+ mcpp_fputc( '\n', ERR); \
+ }
+
+ static int mcpp_getopt(
+ int argc,
+ char * const * argv,
+ const char * opts
+ )
+ /*
+ * 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 <= mcpp_optind ||
+ argv[ mcpp_optind][ 0] != '-'
+ || argv[ mcpp_optind][ 1] == '\0') {
+ return EOF;
+ } else if (ACE_OS::strcmp( argv[ mcpp_optind], "--") == 0) {
+ mcpp_optind++;
+ return EOF;
+ }
+ }
+ /* mcpp_optopt = c = (unsigned char) argv[ mcpp_optind][ sp]; */
+ mcpp_optopt = c = argv[ mcpp_optind][ sp] & UCHARMAX;
+ if (c == ':' || (cp = ACE_OS::strchr( opts, c)) == 0) {
+ OPTERR( error2, c)
+ if (argv[ mcpp_optind][ ++sp] == '\0') {
+ mcpp_optind++;
+ sp = 1;
+ }
+ return '?';
+ }
+ if (*++cp == ':') {
+ if (argv[ mcpp_optind][ sp+1] != '\0') {
+ mcpp_optarg = &argv[ mcpp_optind++][ sp+1];
+ } else if (argc <= ++mcpp_optind) {
+ OPTERR( error1, c)
+ sp = 1;
+ return '?';
+ } else {
+ mcpp_optarg = argv[ mcpp_optind++];
+ }
+ sp = 1;
+ } else {
+ if (argv[ mcpp_optind][ ++sp] == '\0') {
+ sp = 1;
+ mcpp_optind++;
+ }
+ mcpp_optarg = 0;
+ }
+ return c;
+ }
+
+#if defined(HOST_HAVE_STPCPY) && HOST_HAVE_STPCPY == FALSE
+ char * mcpp_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
+
+ /*
+ * list_heap() is a function to print out information of heap-memory.
+ * See "kmmalloc-2.5.3.zip" 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( FALSE, FALSE);
+#endif
+ }
+
+#ifdef MCPP_LIB
+ void clear_filelist( void)
+ /*
+ * Free malloced memory for filename-list and directory-list.
+ */
+ {
+ const char ** incp;
+ INC_LIST * namep;
+
+ for (incp = incdir; incp < incend; incp++)
+ ACE_OS::free( (void *) *incp);
+ ACE_OS::free( (void *) incdir);
+ for (namep = fnamelist; namep < fname_end; namep++)
+ ACE_OS::free( (void *) namep->name);
+ ACE_OS::free( (void *) fnamelist);
+ if (standard)
+ ACE_OS::free( (void *) once_list);
+ }
+#endif
+