diff options
Diffstat (limited to 'TAO/TAO_IDL/contrib/mcpp/main.cpp')
-rw-r--r-- | TAO/TAO_IDL/contrib/mcpp/main.cpp | 507 |
1 files changed, 256 insertions, 251 deletions
diff --git a/TAO/TAO_IDL/contrib/mcpp/main.cpp b/TAO/TAO_IDL/contrib/mcpp/main.cpp index 31ac2de34bb..c87eb156de8 100644 --- a/TAO/TAO_IDL/contrib/mcpp/main.cpp +++ b/TAO/TAO_IDL/contrib/mcpp/main.cpp @@ -1,5 +1,5 @@ /*- $Id$ - * Copyright (c) 1998, 2002-2007 Kiyoshi Matsui <kmatsui@t3.rim.or.jp> + * 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 @@ -42,21 +42,36 @@ #include "internal.H" #endif -#include "ace/Log_Msg.h" -#include "ace/OS_NS_stdio.h" -#include "ace/OS_NS_stdlib.h" - /* Function pointer to expand_macro() functions. */ - char * (*expand_macro)( DEFBUF * defp, char * out, char * out_end); + char * (*expand_macro)( DEFBUF * defp, char * out, char * out_end + , LINE_COL line_col, int * pragma_op); + + /* The boolean flags specified by the execution options. */ + struct option_flags_ option_flags = { + FALSE, /* c: -C (keep comments) */ + FALSE, /* k: -k (keep horizontal white spaces) */ + FALSE, /* z: -z (no output of included files) */ + FALSE, /* p: -P (no #line output) */ + FALSE, /* q: -Q (output diagnosis to mcpp.err) */ + FALSE, /* v: -v (verbose, affects macro notification) */ + TRIGRAPHS_INIT, /* trig: -3 (toggle trigraphs) */ + DIGRAPHS_INIT, /* dig: -2 (toggle digraphs recognition) */ + /* + * lang_asm allows the following non-standard features. + * 1. #non-directive. + * 2. <newline> in a string-literal. + * 3. invalid pp-token generated by ## operator. + * lang_asm is not available in POST_STD mode. + * When COMPILER == GNUC, -x assembler-with-cpp or -lang-asm options + * are used instead of -a. + */ + FALSE, /* lang_asm: -a (assembler source) */ + FALSE, /* no_source_line: -j (no source line in diag) */ + FALSE /* dollar_in_name */ + }; int mcpp_mode = STD; /* Mode of preprocessing */ - int cflag = FALSE; /* -C option (keep comments) */ - int zflag = FALSE; /* -i option (no output of included file) */ - int pflag = FALSE; /* -P option (no #line output) */ - int qflag = FALSE; /* -Q option (diagnostics to "mcpp.err") */ - int trig_flag = TRIGRAPHS_INIT; /* -3 option (trigraphs)*/ - int dig_flag = DIGRAPHS_INIT; /* -2 option (digraphs) */ long cplus_val = 0L; /* Value of __cplusplus for C++ */ long stdc_ver = 0L; /* Value of __STDC_VERSION__ */ int stdc_val = 0; /* Value of __STDC__ */ @@ -65,33 +80,10 @@ (cplus_val >= 199901L) specifies compatible mode to C99 (extended feature of this preprocessor) */ int standard = TRUE; /* TRUE, if mcpp_mode is STD or POST_STD */ - -/* - * lang_asm allows the following non-standard features. - * 1. #non-directive. - * 2. <newline> in a string-literal. - * 3. invalid pp-token generated by ## operator. - * lang_asm is not available in POST_STD mode. - */ - int lang_asm = FALSE; /* -a option (assembler source) */ int std_line_prefix = STD_LINE_PREFIX; /* Output line and file information in C source style */ /* - * Translation limits specified C90, C99 or C++. - */ - /* The following three values are temporarily set for do_options() */ - long str_len_min = NBUFF; /* Least maxmum of string len. */ - size_t id_len_min = IDMAX; /* Least maximum of ident len. */ - int n_mac_pars_min = NMACPARS; /* Least maximum of num of params. */ - int exp_nest_min; /* Least maximum of expr nest */ - int blk_nest_min; /* Least maximum of block nest */ - int inc_nest_min; /* Least maximum of include nest*/ - long n_macro_min; /* Least maximum of num of macros */ - - long line_limit; /* Maximum source line number */ - -/* * Commonly used global variables: * src_line is the current input line number. * wrong_line is set in many places when the actual output line is out of @@ -103,24 +95,24 @@ * infile is the head of a linked list of input files (extended by * #include and macros being expanded). 'infile' always points * to the current file/macro. 'infile->parent' to the includer, - * etc. 'infile->fp' is NULL if this input stream is a macro. + * etc. 'infile->fp' is NULL if this input stream is not a file. * inc_dirp Directory of #includer with trailing PATH_DELIM. This points * to one of incdir[] or to the current directory (represented as - * "". This should not be 0. + * "". This should not be NULL. */ long src_line; /* Current line number */ int wrong_line; /* Force #line to compiler */ int newlines; /* Count of blank lines */ int errors = 0; /* Cpp error counter */ int warn_level = -1; /* Level of warning (have to initialize)*/ - FILEINFO * infile = 0; /* Current input file */ - int include_nest; /* Nesting level of #include */ + FILEINFO * infile = NULL; /* Current input file */ + int include_nest = 0; /* Nesting level of #include */ const char * null = ""; /* "" string for convenience */ const char ** inc_dirp; /* Directory of #includer */ const char * cur_fname; /* Current source file name */ /* cur_fname is not rewritten by #line directive */ - char cur_fullname[ FILENAMEMAX + 1]; - /* Full path of current source file (i.e. *inc_dirp/cur_fname) */ + char * cur_fullname; + /* Full path of current source file (i.e. infile->full_fname) */ int no_source_line; /* Do not output line in diag. */ char identifier[ IDMAX + IDMAX/8]; /* Current identifier */ int mcpp_debug = 0; /* != 0 if debugging now */ @@ -134,6 +126,7 @@ int in_define = FALSE; /* TRUE scanning #define line */ int in_getarg = FALSE; /* TRUE collecting macro arguments */ int in_include = FALSE; /* TRUE scanning #include line */ + int in_if = FALSE; /* TRUE scanning #if and in non-skipped expr. */ long in_asm = 0L; /* Starting line of #asm - #endasm block*/ /* @@ -149,13 +142,6 @@ char * macro_name; /* - * compat_mode is set to TRUE, if recursive macro call is expanded more - * than Standard's specification. This mode is compatible to GCC and - * some other implementations. - */ - int compat_mode = FALSE; - -/* * openum is the return value of scan_op() in support.c. */ int openum; @@ -172,25 +158,31 @@ int mkdep = 0; /* - * If zflag is TRUE, no_output is incremented when a file is #included, - * and decremented when the file is finished. + * If option_flags.z is TRUE, no_output is incremented when a file is + * #included, and decremented when the file is finished. * If no_output is larger than 0, processed files are not output, meanwhile * the macros in the files are defined. - * If mkdep != 0 && (mkdep & MD_FILE) == 0, no_output is set to 1 initially. + * If mkdep != 0 && (mkdep & MD_FILE) == 0, no_output is set to 1 initially. */ int no_output = 0; /* * keep_comments is set TRUE by the -C option. If TRUE, comments are written - * directly to the output stream. This is needed if the output from cpp is - * to be passed to lint (which uses commands embedded in comments). cflag - * contains the permanent state of the -C flag. keep_comments is always - * falsified when compilation is supressed by a false #if or when no_output - * is TRUE. + * directly to the output stream. option_flags.c contains the permanent state + * of the -C option. keep_comments is always falsified when compilation is + * supressed by a false #if or when no_output is TRUE. */ int keep_comments = 0; /* Write out comments flag */ /* + * keep_spaces is set to TRUE by the -k option. If TRUE, spaces and tabs in + * an input line are written out to the output line without squeezing to one + * space. option_flags.k contains the permanent state of the -k option. + * keep_spaces is falsified when compilation is suppressed by a false #if. + */ + int keep_spaces = 0; /* Keep white spaces of line*/ + +/* * ifstack[] holds information about nested #if's. It is always accessed via * ifptr->stat. The information is as follows: * WAS_COMPILING state of compiling flag at outer level. @@ -215,23 +207,16 @@ */ int insert_sep = NO_SEP; -/* - * has_pragma is set to TRUE so as to execute _Pragma() operator when the - * psuedo macro _Pragma() is found. - */ - int has_pragma = FALSE; - /* File pointers for input and output. */ - FILE * fp_in = 0; /* Input stream to preprocess */ - FILE * fp_out = 0; /* Output stream preprocessed */ - FILE * fp_err = 0; /* Diagnostics stream */ - FILE * fp_debug = 0; /* Debugging information stream */ + FILE * fp_in; /* Input stream to preprocess */ + FILE * fp_out; /* Output stream preprocessed */ + FILE * fp_err; /* Diagnostics stream */ + FILE * fp_debug; /* Debugging information stream */ /* Variables on multi-byte character encodings. */ int mbchar = MBCHAR; /* Encoding of multi-byte char */ - int mbmask; /* Char type other than mbchar */ - int mbstart; /* 1st byte of mbchar (or shift)*/ - int bsl_in_mbchar; /* 2nd byte of mbchar has '\\' */ + int mbchk; /* Character type of possible multi-byte char */ + int bsl_in_mbchar; /* 2nd byte of mbchar possibly has '\\' */ int bsl_need_escape; /* '\\' in MBCHAR should be escaped */ /* Function pointer to mb_read_*() functions. */ size_t (*mb_read)( int c1, char ** in_pp, char ** out_pp); @@ -239,24 +224,49 @@ jmp_buf error_exit; /* Exit on fatal error */ /* - * work_buf[] and workp are used to store one piece of text in a temporary + * Translation limits specified by C90, C99 or C++. + */ + struct std_limits_ std_limits = { + /* The following three are temporarily set for do_options() */ + NBUFF, /* Least maximum of string length */ + IDMAX, /* Least maximum of identifier length */ + NMACPARS, /* Least maximum of number of macro params */ + EXP_NEST_CPLUS_MIN, + BLK_NEST_CPLUS_MIN, + INCLUDE_NEST_CPLUS_MIN, + NMACRO_CPLUS_MIN, + LINE_CPLUS_LIMIT + }; + +/* + * work_buf[] and workp are used to store one piece of text as a temporary * buffer. * To initialize storage, set workp = work_buf. Note that the work buffer is * used by several subroutines -- be sure that your data won't be overwritten. * work_buf[] is used for: - * 1. temporary buffer in macro expansion (exp_special(), expand_macro(), - * catenate()) - * 2. temporary buffer in processing directive line. + * 1. macro expansion (def_special(), prescan(), catenate(), + * stringize()). + * 2. processing directive line (directive.c, eval.c, get_unexpandable(), + * do_pragma() and its subroutines). + * 3. processing _Pragma() operator (do_pragma_op()). + * 4. miscellaneous (init_gcc_macro(), curfile()). */ char work_buf[ NWORK + IDMAX]; /* Work buffer */ char * workp; /* Pointer into work_buf[] */ char * const work_end = & work_buf[ NWORK]; /* End of buffer of work_buf[] */ +/* + * src_col is the current input column number, but is rarely used. + * It is used to put spaces after #line line in keep_spaces mode + * on some special cases. + */ +static int src_col = 0; /* Column number of source line */ + #define MBCHAR_IS_ESCAPE_FREE (SJIS_IS_ESCAPE_FREE && \ BIGFIVE_IS_ESCAPE_FREE && ISO2022_JP_IS_ESCAPE_FREE) -#if MCPP_LIB +#ifdef MCPP_LIB static void init_main( void); /* Initialize static variables */ #endif @@ -272,8 +282,10 @@ static char * de_stringize( char * in, char * out); /* "De-stringize" for _Pragma() op. */ static void putout( char * out); /* May concatenate adjacent string */ +#if COMPILER != GNUC && COMPILER != MSC static void devide_line( char * out); /* Devide long line for compiler */ +#endif static void put_a_line( char * out); /* Put out the processed line */ #if ! HAVE_DIGRAPHS || ! MBCHAR_IS_ESCAPE_FREE @@ -285,41 +297,41 @@ static char * conv_a_digraph( char * cp); #endif #if ! MBCHAR_IS_ESCAPE_FREE static char * esc_mbchar( char * str, char * str_end); - /* Insert \ before 2nd byte of SJIS */ + /* Double \ as 2nd byte of SJIS */ #endif #endif -#if MCPP_LIB +#ifdef MCPP_LIB static void init_main( void) /* Initialize global variables on re-entering. */ { mcpp_mode = STD; - cflag = zflag = pflag = qflag = FALSE; - trig_flag = TRIGRAPHS_INIT; - dig_flag = DIGRAPHS_INIT; cplus_val = stdc_ver = 0L; stdc_val = 0; standard = TRUE; - lang_asm = FALSE; std_line_prefix = STD_LINE_PREFIX; - str_len_min = NBUFF; - id_len_min = IDMAX; - n_mac_pars_min = NMACPARS; - errors = 0; + errors = src_col = 0; warn_level = -1; infile = 0; - in_directive = in_define = in_getarg = in_include = FALSE; - in_asm = 0L; - macro_line = 0L; - compat_mode = FALSE; - mcpp_debug = mkdep = no_output = keep_comments = 0; - ifstack[0].stat = WAS_COMPILING; - ifstack[0].ifline = ifstack[0].elseline = 0L; - ifptr = ifstack; + in_directive = in_define = in_getarg = in_include = in_if = FALSE; + src_line = macro_line = in_asm = 0L; + mcpp_debug = mkdep = no_output = keep_comments = keep_spaces = 0; + include_nest = 0; insert_sep = NO_SEP; - has_pragma = FALSE; mbchar = MBCHAR; + ifptr = ifstack; + ifstack[0].stat = WAS_COMPILING; + ifstack[0].ifline = ifstack[0].elseline = 0L; + std_limits.str_len = NBUFF; + std_limits.id_len = IDMAX; + std_limits.n_mac_pars = NMACPARS; + option_flags.c = option_flags.k = option_flags.z = option_flags.p + = option_flags.q = option_flags.v = option_flags.lang_asm + = option_flags.no_source_line = option_flags.dollar_in_name + = FALSE; + option_flags.trig = TRIGRAPHS_INIT; + option_flags.dig = DIGRAPHS_INIT; } int mcpp_lib_main @@ -331,29 +343,26 @@ int main char ** argv ) { - char * in_file = 0; - char * out_file = 0; + char * in_file = 0; + char * out_file = 0; + char * stdin_name = "<stdin>"; - if (setjmp( error_exit) != 0) - { - ACE_DEBUG ((LM_DEBUG, "setjmp failed\n")); + if (setjmp( error_exit) == -1) { + errors++; goto fatal_error_exit; - } + } -#if MCPP_LIB - /* Initialize static variables. */ +#ifdef MCPP_LIB + /* Initialize global and static variables. */ init_main(); init_directive(); init_eval(); init_support(); init_system(); -#if NEED_GETOPT - init_lib(); -#endif #endif - fp_in = 0; - fp_out = 0; + fp_in = stdin; + fp_out = stdout; fp_err = stderr; fp_debug = stdout; /* @@ -362,101 +371,91 @@ int main */ inc_dirp = &null; /* Initialize to current (null) directory */ - cur_fname = "(predefined)"; /* For predefined macros */ + cur_fname = cur_fullname = "(predefined)"; /* For predefined macros */ init_defines(); /* Predefine macros */ mb_init(); /* Should be initialized prior to get options */ do_options( argc, argv, &in_file, &out_file); /* Command line options */ + /* Open input file, "-" means stdin. */ if (in_file != 0 && ! str_eq( in_file, "-")) { if ((fp_in = ACE_OS::fopen( in_file, "r")) == 0) { - ACE_ERROR((LM_ERROR, "Can't open input file \"%s\".\n", in_file)); -#if MCPP_LIB + mcpp_fprintf( ERR, "Can't open input file \"%s\".\n", in_file); + errors++; +#ifdef MCPP_LIB goto fatal_error_exit; #else return( IO_ERROR); #endif } - ACE_OS::strcpy( work_buf, in_file); /* Remember input filename */ } else { - ACE_OS::strcpy( work_buf, "<stdin>"); + in_file = stdin_name; } - /* Open output file, "-" means stdout. */ if (out_file != 0 && ! str_eq( out_file, "-")) { - if ((fp_out = ACE_OS::fopen( out_file, "w")) == 0) { - ACE_ERROR((LM_ERROR, "Can't open output file \"%s\".\n", out_file)); -#if MCPP_LIB + if ((fp_out = ACE_OS::fopen( out_file, "w")) == 0) { + mcpp_fprintf( ERR, "Can't open output file \"%s\".\n", out_file); + errors++; +#ifdef MCPP_LIB goto fatal_error_exit; #else return( IO_ERROR); #endif } + fp_debug = fp_out; } - if (qflag) { /* Redirect diagnostics */ - if (ACE_OS::freopen( "mcpp.err", "a", fp_err) == 0) { - ACE_ERROR((LM_ERROR, "Can't open \"mcpp.err\"\n")); -#if MCPP_LIB + if (option_flags.q) { /* Redirect diagnostics */ + if ((fp_err = ACE_OS::fopen( "mcpp.err", "a")) == 0) { + errors++; + mcpp_fprintf( OUT, "Can't open \"mcpp.err\"\n"); +#ifdef MCPP_LIB goto fatal_error_exit; #else return( IO_ERROR); #endif } } - - if (fp_in == 0) fp_in = stdin; - if (fp_out == 0) fp_out = stdout; - - add_file( fp_in, work_buf); /* "open" main input file */ + init_sys_macro(); /* Initialize system-specific macros */ + add_file( fp_in, 0, in_file, in_file, FALSE); + /* "open" main input file */ infile->dirp = inc_dirp; - ACE_OS::strcpy( cur_fullname, work_buf); - if (mkdep && str_eq( infile->real_fname, "<stdin>") == FALSE) - put_depend( work_buf); /* Putout target file name */ + infile->sys_header = FALSE; + cur_fullname = in_file; + if (mkdep && str_eq( infile->real_fname, stdin_name) == FALSE) + put_depend( in_file); /* Putout target file name */ at_start(); /* Do the pre-main commands */ + mcpp_main(); /* Process main file */ + if (mkdep) put_depend( 0); /* Append '\n' to dependency line */ at_end(); /* Do the final commands */ fatal_error_exit: -#if MCPP_LIB - // ACE_DEBUG ((LM_DEBUG, "fatal_error_exit\n")); +#ifdef MCPP_LIB /* Free malloced memory */ + if (mcpp_debug & MACRO_CALL) { + if (in_file != stdin_name) + ACE_OS::free( in_file); + } clear_filelist(); clear_symtable(); #endif + if (fp_in != stdin) + ACE_OS::fclose( fp_in); + if (fp_out != stdout) + ACE_OS::fclose( fp_out); + if (fp_err != stderr) + ACE_OS::fclose( fp_err); + if (mcpp_debug & MEMORY) print_heap(); - if (errors > 0 && no_source_line == FALSE) { - ACE_ERROR((LM_ERROR, "%d error%s in preprocessor.\n", - errors, (errors == 1) ? "" : "s")); + if (errors > 0 && option_flags.no_source_line == FALSE) { + mcpp_fprintf( ERR, "%d error%s in preprocessor.\n", + errors, (errors == 1) ? "" : "s"); return IO_ERROR; } - - if (fp_out != 0) - { - ACE_OS::fclose (fp_out); - } - return IO_SUCCESS; /* No errors or -E option set */ -} - -void sharp( void) -/* - * Output a line number line. - */ -{ - if (no_output || pflag || infile == 0) - goto sharp_exit; - if (keep_comments) - mcpp_fputc( '\n', OUT); /* Ensure to be on line top */ - if (std_line_prefix) - mcpp_fprintf( OUT, "#line %ld", src_line); - else - mcpp_fprintf( OUT, "%s%ld", LINE_PREFIX, src_line); - cur_file(); - mcpp_fputc( '\n', OUT); -sharp_exit: - wrong_line = FALSE; + return IO_SUCCESS; /* No errors */ } /* @@ -471,12 +470,6 @@ typedef struct pre_set { static PRESET preset[] = { -#ifdef CPU_OLD - { CPU_OLD, "1"}, -#endif -#ifdef CPU_SP_OLD - { CPU_SP_OLD, "1"}, -#endif #ifdef SYSTEM_OLD { SYSTEM_OLD, "1"}, #endif @@ -492,15 +485,6 @@ static PRESET preset[] = { { 0, 0}, /* End of macros beginning with alphabet */ -#ifdef CPU_STD - { CPU_STD, "1"}, -#endif -#ifdef CPU_STD1 - { CPU_STD1, "1"}, -#endif -#ifdef CPU_STD2 - { CPU_STD2, "1"}, -#endif #ifdef SYSTEM_STD { SYSTEM_STD, "1"}, #endif @@ -547,9 +531,6 @@ static PRESET preset[] = { #ifdef COMPILER_SP3 { COMPILER_SP3, COMPILER_SP3_VAL}, #endif -#ifdef COMPILER_SP4 - { COMPILER_SP4, COMPILER_SP4_VAL}, -#endif #ifdef COMPILER_CPLUS { COMPILER_CPLUS, COMPILER_CPLUS_VAL}, #endif @@ -561,22 +542,26 @@ static void init_defines( void) * Initialize the built-in #define's. * Called only on cpp startup prior to do_options(). * - * Note: the built-in static definitions are removed by the -N option, - * definitions beginning with alphabet are removed by the -S1 option, + * Note: the built-in static definitions are removed by the -N option. */ { int n = sizeof preset / sizeof (PRESET); + int nargs; PRESET * pp; /* Predefine the built-in symbols. */ + nargs = DEF_NOARGS_PREDEF_OLD; for (pp = preset; pp < preset + n; pp++) { if (pp->name && *(pp->name)) - look_and_install( pp->name, DEF_NOARGS - 1, null, pp->val); + look_and_install( pp->name, nargs, null, pp->val); + else if (! pp->name) + nargs = DEF_NOARGS_PREDEF; } - look_and_install( "__MCPP", DEF_NOARGS - 1, null, "2"); + look_and_install( "__MCPP", DEF_NOARGS_PREDEF, null, "2"); /* MCPP V.2.x */ - /* This macro is predefined yet can be undefined by -U or #undef. */ + /* This macro is predefined and is not undefined by -N option, */ + /* yet can be undefined by -U or #undef. */ } void un_predefine( @@ -593,30 +578,9 @@ void un_predefine( for (pp = preset; pp < preset + n; pp++) { if (pp->name) { if (*(pp->name) && (defp = look_id( pp->name)) != 0 - && defp->nargs == DEF_NOARGS - 1) + && defp->nargs >= DEF_NOARGS_PREDEF) undefine( pp->name); - } else if (clearall == FALSE) { /* -S<n> option */ - break; - } - } -} - -void undef_a_predef( - const char * name -) -/* - * Remove a predefined name from the preset[] table so that the name can be - * redefined by -D option. - * The strange ordering (insert, command-line-scan, remove) - * is needed to avoid interaction with -D arguments. - */ -{ - PRESET * pp; - int n = sizeof preset / sizeof (PRESET); - - for (pp = preset; pp < preset + n; pp++) { - if (pp->name && *(pp->name) && str_eq( pp->name, name)) { - pp->name = ""; + } else if (clearall == FALSE) { /* -S<n> option */ break; } } @@ -629,7 +593,7 @@ void undef_a_predef( */ static char output[ NMACWORK]; /* Buffer for preprocessed line */ static char * const out_end = & output[ NWORK - 2]; - /* Limit of output line */ + /* Limit of output line for other than GCC and VC */ static char * const out_wend = & output[ NMACWORK - 2]; /* Buffer end of output line */ static char * out_ptr; /* Current pointer into output[]*/ @@ -644,14 +608,11 @@ static void mcpp_main( void) char * wp; /* Temporary pointer */ DEFBUF * defp; /* Macro definition */ int line_top; /* Is in the line top, possibly spaces */ + LINE_COL line_col; /* Location of macro call in source */ - if (! no_output) { /* Explicitly output a #line at the start of cpp */ - src_line++; - sharp(); - put_info(); /* -fworking-directory */ - src_line--; - } - keep_comments = cflag && !no_output; + keep_comments = option_flags.c && !no_output; + keep_spaces = option_flags.k; /* Will be turned off if !compiling */ + line_col.col = line_col.line = 0L; /* * This loop is started "from the top" at the beginning of each line. @@ -669,16 +630,17 @@ static void mcpp_main( void) while (1) { /* For each line, ... */ out_ptr = output; /* Top of the line buf */ c = get_ch(); - while (c == ' ' || c == '\t' - || (mcpp_mode == OLD_PREP && c == COM_SEP)) { - if (c == ' ' || c == '\t') + if (src_col) + break; /* There is a residual tokens on the line */ + while (char_type[ c] & HSP) { /* ' ' or '\t' */ + if (c != COM_SEP) *out_ptr++ = c; /* Retain line top white spaces */ /* Else skip 0-length comment */ c = get_ch(); } if (c == '#') { /* Is 1st non-space '#' */ directive(); /* Do a #directive */ - } else if (mcpp_mode == STD && dig_flag && c == '%') { + } else if (mcpp_mode == STD && option_flags.dig && c == '%') { /* In POST_STD digraphs are already converted */ if (get_ch() == ':') { /* '%:' i.e. '#' */ directive(); /* Do a #directive */ @@ -720,9 +682,14 @@ static void mcpp_main( void) wrong_line = FALSE; } else { if (wrong_line || newlines > 10) { - sharp(); /* Output # line number */ - } else { /* If just a few, stuff */ - while (newlines-- > 0) /* them out ourselves */ + sharp( 0, 0); /* Output # line number */ + if (keep_spaces && src_col) { + while (src_col--) /* Adjust columns */ + mcpp_fputc( ' ', OUT); + src_col = 0; + } + } else { /* If just a few, stuff */ + while (newlines-- > 0) /* them out ourselves */ mcpp_fputc('\n', OUT); } } @@ -732,36 +699,49 @@ static void mcpp_main( void) */ line_top = TRUE; while (c != '\n' && c != CHAR_EOF) { /* For the whole line */ + /* + * has_pragma is set to TRUE so as to execute _Pragma() operator + * when the psuedo macro _Pragma() is found. + */ + int has_pragma; + + if ((mcpp_debug & MACRO_CALL) && ! in_directive) { + line_col.line = src_line; /* Location in source */ + line_col.col = infile->bptr - infile->buffer - 1; + } if (scan_token( c, (wp = out_ptr, &wp), out_wend) == NAM && (defp = is_macro( &wp)) != 0) { /* A macro */ - wp = expand_macro( defp, out_ptr, out_wend); - /* Expand it completely */ + wp = expand_macro( defp, out_ptr, out_wend, line_col + , & has_pragma); /* Expand it completely */ if (line_top) { /* The first token is a macro */ char * tp = out_ptr; - while (*tp == ' ') + while (char_type[ *tp & UCHARMAX] & HSP) tp++; /* Remove excessive spaces */ ACE_OS::memmove( out_ptr, tp, ACE_OS::strlen( tp) + 1); wp -= (tp - out_ptr); } if (has_pragma) { /* Found _Pramga() */ do_pragma_op(); /* Do _Pragma() operator*/ - has_pragma = FALSE; /* Reset signal */ out_ptr = output; /* Do the rest of line */ wrong_line = TRUE; /* Line-num out of sync */ } else { out_ptr = wp; } + if (keep_spaces && wrong_line && infile + && *(infile->bptr) != '\n' && *(infile->bptr) != EOS) { + src_col = infile->bptr - infile->buffer; + /* Remember the current colums */ + break; /* Do sharp() now */ + } } else { /* Not a macro call */ out_ptr = wp; /* Advance the place */ if (wrong_line) /* is_macro() swallowed */ break; /* the newline */ } - if ((c = get_ch()) == ' ') { /* Token separator */ - *out_ptr++ = ' '; - c = get_ch(); /* First of token */ + while (char_type[ c = get_ch()] & HSP) { /* Horizontal space */ + if (c != COM_SEP) /* Skip 0-length comment*/ + *out_ptr++ = c; } - if (mcpp_mode == OLD_PREP && c == COM_SEP) - c = get_ch(); /* Skip 0-length comment*/ line_top = FALSE; /* Read over some token */ } /* Loop for line */ @@ -778,6 +758,8 @@ static void do_pragma_op( void) * surrounded by other token sequences. * Since all the macros have been expanded completely, any name identical to * macro should not be re-expanded. + * However, a macro in the string argument of _Pragma() may be expanded by + * do_pragma() after de_stringize(), if EXPAND_PRAGMA == TRUE. */ { FILEINFO * file; @@ -789,8 +771,8 @@ static void do_pragma_op( void) file = unget_string( out_ptr, 0); while (c = get_ch(), file == infile) { - if (c == ' ') { - *out_ptr++ = ' '; + if (char_type[ c] & HSP) { + *out_ptr++ = c; continue; } if (scan_token( c, (cp1 = out_ptr, &cp1), out_wend) @@ -798,11 +780,12 @@ static void do_pragma_op( void) && defp->nargs == DEF_PRAGMA) { /* _Pragma() operator */ if (prev) { putout( output); /* Putout the previous sequence */ - cp1 = mcpp_stpcpy( output, "pragma "); /* From top of buffer */ + cp1 = stpcpy( output, "pragma "); /* From top of buffer */ } + /* is_macro() already read over possible spaces after _Pragma */ *cp1++ = get_ch(); /* '(' */ - while ((c = get_ch()) == ' ') - *cp1++ = ' '; + while (char_type[ c = get_ch()] & HSP) + *cp1++ = c; if (((token_type = scan_token( c, (cp2 = cp1, &cp1), out_wend)) != STR && token_type != WSTR)) { /* Not a string literal */ @@ -810,8 +793,8 @@ static void do_pragma_op( void) return; } workp = de_stringize( cp2, work_buf); - while ((c = get_ch()) == ' ') - *cp1++ = ' '; + while (char_type[ c = get_ch()] & HSP) + *cp1++ = c; if (c != ')') { /* More than a string literal */ unget_ch(); put_seq( output, cp1); @@ -862,8 +845,7 @@ static char * de_stringize( */ { char * in_p; - int c1; - int c; + int c1, c; in_p = in; if (*in_p == 'L') @@ -892,17 +874,22 @@ static void putout( #if ! MBCHAR_IS_ESCAPE_FREE post_preproc( out); #elif ! HAVE_DIGRAPHS - if (mcpp_mode == STD && dig_flag) + if (mcpp_mode == STD && option_flag.dig) post_preproc( out); #endif /* Else no post-preprocess */ +#if COMPILER != GNUC && COMPILER != MSC + /* GCC and Visual C can accept very long line */ len = ACE_OS::strlen( out); if (len > NWORK - 1) - devide_line( out); + devide_line( out); /* Devide a too long line */ else +#endif put_a_line( out); } +#if COMPILER != GNUC && COMPILER != MSC + static void devide_line( char * out /* 'out' is 'output' in actual */ ) @@ -920,9 +907,10 @@ static void devide_line( wp = out_ptr = out; while ((c = get_ch()), file == infile) { - if (c == ' ') { - if (out == out_ptr || *(out_ptr - 1) != ' ') { - *out_ptr++ = ' '; + if (char_type[ c] & HSP) { + if (keep_spaces || out == out_ptr + || (char_type[ *(out_ptr - 1) & UCHARMAX] & HSP)) { + *out_ptr++ = c; wp++; } continue; @@ -931,12 +919,25 @@ static void devide_line( if (NWORK-2 < wp - out_ptr) { /* Too long a token */ cfatal( "Too long token %s", out_ptr, 0L, 0); /* _F_ */ } else if (out_end <= wp) { /* Too long line */ + if (mcpp_debug & MACRO_CALL) { /* -K option */ + /* Other than GCC or Visual C */ + /* scan_token() scans a comment as sequence of some */ + /* tokens such as '/', '*', ..., '*', '/', since it */ + /* does not expect comment. */ + save = out_ptr; + while ((save = ACE_OS::strrchr( save, '/')) != 0) { + if (*(save - 1) == '*') { /* '*' '/' sequence */ + out_ptr = save + 1; /* Devide at the end*/ + break; /* of a comment*/ + } + } + } save = save_string( out_ptr); /* Save the token */ *out_ptr++ = '\n'; /* Append newline */ *out_ptr = EOS; put_a_line( out); /* Putout the former tokens */ - wp = out_ptr = mcpp_stpcpy( out, save); /* Restore the token */ - ACE_OS::free( save); + wp = out_ptr = stpcpy( out, save); /* Restore the token */ + ACE_OS::free( save); } else { /* Still in size */ out_ptr = wp; /* Advance the pointer */ } @@ -944,9 +945,11 @@ static void devide_line( unget_ch(); /* Push back the source character */ put_a_line( out); /* Putout the last tokens */ - sharp(); /* Correct line number */ + sharp( 0, 0); /* Correct line number */ } +#endif + static void put_a_line( char * out ) @@ -968,8 +971,7 @@ static void put_a_line( *++out_p = '\n'; *++out_p = EOS; } - - if (mcpp_fputs ( out, OUT) == EOF) + if (mcpp_fputs( out, OUT) == EOF) cfatal( "File write error", 0, 0L, 0); /* _F_ */ } @@ -999,6 +1001,8 @@ static int post_preproc( /* * Convert digraphs and double '\\' of the second byte of SJIS (BIGFIVE or * ISO2022_JP). + * Note: Output of -K option embeds macro informations into comments. + * scan_token() does not recognize comment and parses it as '/', '*', etc. */ { #if ! HAVE_DIGRAPHS @@ -1011,8 +1015,8 @@ static int post_preproc( unget_string( out, 0); while ((c = get_ch()) != '\n') { /* Not to read over to next line */ - if (c == ' ') { - *cp++ = ' '; + if (char_type[ c] & HSP) { + *cp++ = c; continue; } str = cp; @@ -1108,23 +1112,24 @@ static char * esc_mbchar( if ((delim = *str++) == 'L') delim = *str++; /* The quote character */ while ((c = *str++ & UCHARMAX) != delim) { - if (char_type[ c] & mbstart) { /* MBCHAR */ + if (char_type[ c] & mbchk) { /* MBCHAR */ cp = str; mb_read( c, &str, (workp = work_buf, &workp)); while (cp++ < str) { c = *(cp - 1); if (c == '\\' || c == '"' || c == '\'') { /* Insert \ before 0x5c, 0x22, 0x27 */ - ACE_OS::memmove( cp, cp - 1, (size_t) (str_end - cp) + 2); + ACE_OS::memmove( cp, cp - 1, (size_t) (str_end - cp) + 2); *(cp++ - 1) = '\\'; str++; str_end++; } } - } else if (c == '\\' && ! (char_type[ *str & UCHARMAX] & mbstart)) { + } else if (c == '\\' && ! (char_type[ *str & UCHARMAX] & mbchk)) { str++; /* Escape sequence */ } } return str_end; } #endif /* ! MBCHAR_IS_ESCAPE_FREE */ + |