/* C Compatible Compiler Preprocessor (CCCP)
- Copyright (C) 1986, 87, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000 Free Software Foundation, Inc.
Written by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
#include "config.h"
-#define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
-
-#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
-#define PRINTF_PROTO_2(ARGS) PRINTF_PROTO(ARGS, 2, 3)
-#define PRINTF_PROTO_3(ARGS) PRINTF_PROTO(ARGS, 3, 4)
-#define PRINTF_PROTO_4(ARGS) PRINTF_PROTO(ARGS, 4, 5)
-
#include "system.h"
-#include <sys/stat.h>
#include <signal.h>
#ifdef HAVE_SYS_RESOURCE_H
typedef unsigned char U_CHAR;
#include "pcp.h"
+#include "intl.h"
+#include "prefix.h"
+#include "version.h"
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
# define STANDARD_INCLUDE_DIR "/usr/include"
#endif
-/* By default, colon separates directories in a path. */
-#ifndef PATH_SEPARATOR
-# define PATH_SEPARATOR ':'
-#endif
-
/* By default, the suffix for object files is ".o". */
#ifdef OBJECT_SUFFIX
# define HAVE_OBJECT_SUFFIX
#define fopen(fname,mode) VMS_fopen (fname,mode)
#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
+#define fwrite(ptr,size,nitems,stream) VMS_fwrite (ptr,size,nitems,stream)
static int VMS_fstat (), VMS_stat ();
static int VMS_open ();
static FILE *VMS_fopen ();
static FILE *VMS_freopen ();
-static int hack_vms_include_specification ();
+static size_t VMS_fwrite ();
+static void hack_vms_include_specification ();
#define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
#define INO_T_HASH(a) 0
#define INCLUDE_LEN_FUDGE 12 /* leave room for VMS syntax conversion */
#endif /* VMS */
-/* Windows does not natively support inodes, and neither does MSDOS. */
-#if (defined (_WIN32) && ! defined (CYGWIN32)) || defined (__MSDOS__)
+/* Windows does not natively support inodes, and neither does MSDOS.
+ Cygwin's emulation can generate non-unique inodes, so don't use it. */
+#if (defined (_WIN32) && ! defined (_UWIN)) \
+ || defined (__MSDOS__)
#define INO_T_EQ(a, b) 0
#endif
-#undef MIN
-#undef MAX
-#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
-#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
-
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
-
-#ifndef S_ISREG
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-
-#ifndef S_ISDIR
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-
#ifndef INO_T_EQ
#define INO_T_EQ(a, b) ((a) == (b))
#endif
/* External declarations. */
-extern char *version_string;
-extern char *update_path PROTO((char *, char *));
-HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
-HOST_WIDE_INT parse_c_expression PROTO((char *, int));
+HOST_WIDEST_INT parse_escape PARAMS ((char **, HOST_WIDEST_INT));
+HOST_WIDEST_INT parse_c_expression PARAMS ((char *, int));
\f
/* Name under which this program was invoked. */
-static char *progname;
+static const char *progname;
/* Nonzero means use extra default include directories for C++. */
static int warn_undef;
+/* Nonzero means warn if we find white space where it doesn't belong. */
+
+static int warn_white_space;
+
/* Nonzero means warn if #import is used. */
static int warn_import = 1;
int c89;
+/* Nonzero for the 1999 C Standard. */
+
+int c99;
+
/* Nonzero causes output not to be done,
but directives such as #define that have side effects
are still obeyed. */
and for expanding macro arguments. */
#define INPUT_STACK_MAX 400
static struct file_buf {
- char *fname;
+ const char *fname;
/* Filename specified with #line directive. */
- char *nominal_fname;
+ const char *nominal_fname;
/* The length of nominal_fname, which may contain embedded NULs. */
size_t nominal_fname_len;
/* Include file description. */
/* -I directories are added to the end, then the defaults are added. */
/* The */
static struct default_include {
- char *fname; /* The name of the directory. */
- char *component; /* The component containing the directory */
+ const char *fname; /* The name of the directory. */
+ const char *component; /* The component containing the directory */
int cplusplus; /* Only look here if we're compiling C++. */
int cxx_aware; /* Includes in this directory don't need to
be wrapped in extern "C" when compiling
C++. */
+ int included; /* Set if the directory is acceptable. */
} include_defaults_array[]
#ifdef INCLUDE_DEFAULTS
= INCLUDE_DEFAULTS;
#else
= {
/* Pick up GNU C++ specific include files. */
- { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
+ { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 },
#ifdef CROSS_COMPILE
/* This is the dir for fixincludes. Put it just before
the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
+ { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
/* For cross-compilation, this dir name is generated
automatically in Makefile.in. */
- { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
+ { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 },
#ifdef TOOL_INCLUDE_DIR
/* This is another place that the target system's headers might be. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 },
+ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 },
#endif
#else /* not CROSS_COMPILE */
#ifdef LOCAL_INCLUDE_DIR
/* This should be /usr/local/include and should come before
the fixincludes-fixed header files. */
- { LOCAL_INCLUDE_DIR, 0, 0, 1 },
+ { LOCAL_INCLUDE_DIR, 0, 0, 1, 0 },
#endif
#ifdef TOOL_INCLUDE_DIR
/* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 },
+ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 },
#endif
/* This is the dir for fixincludes. Put it just before
the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
+ { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
/* Some systems have an extra dir of include files. */
#ifdef SYSTEM_INCLUDE_DIR
- { SYSTEM_INCLUDE_DIR, 0, 0, 0 },
+ { SYSTEM_INCLUDE_DIR, 0, 0, 0, 0 },
#endif
#ifndef STANDARD_INCLUDE_COMPONENT
#define STANDARD_INCLUDE_COMPONENT 0
#endif
- { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
+ { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 0 },
#endif /* not CROSS_COMPILE */
- { 0, 0, 0, 0 }
+ { 0, 0, 0, 0, 0 }
};
#endif /* no INCLUDE_DEFAULTS */
was seen in this include file, or #import was applied to the file.
Otherwise, if it is nonzero, it is a macro name.
Don't include the file again if that macro is defined. */
- U_CHAR *control_macro;
+ const U_CHAR *control_macro;
/* Nonzero if the dependency on this include file has been output. */
int deps_output;
struct stat st;
struct macrodef
{
struct definition *defn;
- U_CHAR *symnam;
+ const U_CHAR *symnam;
int symlen;
};
\f
/* came from the command line */
U_CHAR *expansion;
int line; /* Line number of definition */
- char *file; /* File of definition */
+ const char *file; /* File of definition */
size_t file_len; /* Length of file (which can contain NULs) */
char rest_args; /* Nonzero if last arg. absorbs the rest */
struct reflist {
/* different kinds of things that can appear in the value field
of a hash node. Actually, this may be useless now. */
union hashval {
- char *cpval;
+ const char *cpval;
DEFINITION *defn;
KEYDEF *keydef;
};
static char rest_extension[] = "...";
#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
+/* This is the implicit parameter name when using variable number of
+ parameters for macros using the ISO C 99 extension. */
+static char va_args_name[] = "__VA_ARGS__";
+#define VA_ARGS_NAME_LENGTH (sizeof (va_args_name) - 1)
+
/* The structure of a node in the hash table. The hash table
has entries for all tokens defined by #define directives (type T_MACRO),
plus some special tokens like __LINE__ (these each have their own
T_DISABLED, /* macro temporarily turned off for rescan */
T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */
+ T_POISON, /* defined with `#pragma poison' */
T_UNUSED /* Used for something not defined. */
};
#define HASHSTEP(old, c) ((old << 2) + c)
#define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */
-/* Symbols to predefine. */
-
-#ifdef CPP_PREDEFINES
-static char *predefs = CPP_PREDEFINES;
-#else
-static char *predefs = "";
-#endif
\f
/* We let tm.h override the types used here, to handle trivial differences
such as the choice of unsigned int or long unsigned int for size_t.
#ifndef WCHAR_TYPE
#define WCHAR_TYPE "int"
#endif
-char * wchar_type = WCHAR_TYPE;
+static const char * wchar_type = WCHAR_TYPE;
#undef WCHAR_TYPE
/* The string value for __USER_LABEL_PREFIX__ */
#ifndef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX ""
#endif
-char * user_label_prefix = USER_LABEL_PREFIX;
+static const char * user_label_prefix = USER_LABEL_PREFIX;
#undef USER_LABEL_PREFIX
/* The string value for __REGISTER_PREFIX__ */
\f
/* `struct directive' defines one #-directive, including how to handle it. */
-#define DO_PROTO PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *))
+#define DO_PROTO PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *))
struct directive {
int length; /* Length of name */
int (*func) DO_PROTO; /* Function to handle directive */
- char *name; /* Name of directive */
+ const char *name; /* Name of directive */
enum node_type type; /* Code which describes which directive. */
};
#endif
static int do_unassert DO_PROTO;
static int do_undef DO_PROTO;
-static int do_warning DO_PROTO;
static int do_xifdef DO_PROTO;
/* Here is the actual list of #-directives, most-often-used first. */
{ 6, do_include, "import", T_IMPORT},
{ 5, do_undef, "undef", T_UNDEF},
{ 5, do_error, "error", T_ERROR},
- { 7, do_warning, "warning", T_WARNING},
+ { 7, do_error, "warning", T_WARNING},
#ifdef SCCS_DIRECTIVE
{ 4, do_sccs, "sccs", T_SCCS},
#endif
static U_CHAR is_hor_space[256];
/* table to tell if c is horizontal or vertical space. */
U_CHAR is_space[256];
-/* names of some characters */
-static char *char_name[256];
#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
static int errors = 0; /* Error counter for exit code */
/* Name of output file, for error messages. */
-static char *out_fname;
+static const char *out_fname;
+/* Nonzero to ignore \ in string constants. Use to treat #line 1 "A:\file.h
+ as a non-form feed. If you want it to be a form feed, you must use
+ # 1 "\f". */
+static int ignore_escape_flag = 1;
/* Stack of conditionals currently in progress
(including both successful and failing conditionals). */
struct if_stack {
struct if_stack *next; /* for chaining to the next stack frame */
- char *fname; /* copied from input when frame is made */
+ const char *fname; /* copied from input when frame is made */
size_t fname_len; /* similarly */
int lineno; /* similarly */
int if_succeeded; /* true if a leg of this if-group
has been passed through rescan */
- U_CHAR *control_macro; /* For #ifndef at start of file,
+ const U_CHAR *control_macro; /* For #ifndef at start of file,
this is the macro name tested. */
enum node_type type; /* type of last directive seen in this group */
};
so don't look for #include "foo" the source-file directory. */
static int ignore_srcdir;
\f
-static int safe_read PROTO((int, char *, int));
-static void safe_write PROTO((int, char *, int));
-static void eprint_string PROTO((char *, size_t));
+static int safe_read PARAMS ((int, char *, int));
+static void safe_write PARAMS ((int, const char *, int));
-int main PROTO((int, char **));
+int main PARAMS ((int, char **));
-static void path_include PROTO((char *));
+static void path_include PARAMS ((char *));
-static U_CHAR *index0 PROTO((U_CHAR *, int, size_t));
+static const U_CHAR *index0 PARAMS ((const U_CHAR *, int, size_t));
-static void trigraph_pcp PROTO((FILE_BUF *));
+static void trigraph_pcp PARAMS ((FILE_BUF *));
+static void check_white_space PARAMS ((FILE_BUF *));
-static void newline_fix PROTO((U_CHAR *));
-static void name_newline_fix PROTO((U_CHAR *));
+static void newline_fix PARAMS ((U_CHAR *));
+static void name_newline_fix PARAMS ((U_CHAR *));
-static char *get_lintcmd PROTO((U_CHAR *, U_CHAR *, U_CHAR **, int *, int *));
+static const char *get_lintcmd PARAMS ((const U_CHAR *, const U_CHAR *,
+ const U_CHAR **, int *, int *));
-static void rescan PROTO((FILE_BUF *, int));
+static void rescan PARAMS ((FILE_BUF *, int));
-static FILE_BUF expand_to_temp_buffer PROTO((U_CHAR *, U_CHAR *, int, int));
+static FILE_BUF expand_to_temp_buffer PARAMS ((const U_CHAR *, const U_CHAR *,
+ int, int));
-static int handle_directive PROTO((FILE_BUF *, FILE_BUF *));
+static int handle_directive PARAMS ((FILE_BUF *, FILE_BUF *));
-static struct tm *timestamp PROTO((void));
-static void special_symbol PROTO((HASHNODE *, FILE_BUF *));
+static struct tm *timestamp PARAMS ((void));
+static void special_symbol PARAMS ((HASHNODE *, FILE_BUF *));
-static int is_system_include PROTO((char *));
-static char *base_name PROTO((char *));
-static int absolute_filename PROTO((char *));
-static size_t simplify_filename PROTO((char *));
+static int is_system_include PARAMS ((const char *));
+static char *base_name PARAMS ((const char *));
+static int absolute_filename PARAMS ((const char *));
+static size_t simplify_filename PARAMS ((char *));
-static char *read_filename_string PROTO((int, FILE *));
-static struct file_name_map *read_name_map PROTO((char *));
-static int open_include_file PROTO((char *, struct file_name_list *, U_CHAR *, struct include_file **));
-static char *remap_include_file PROTO((char *, struct file_name_list *));
-static int lookup_ino_include PROTO((struct include_file *));
+static char *read_filename_string PARAMS ((int, FILE *));
+static struct file_name_map *read_name_map PARAMS ((const char *));
+static int open_include_file PARAMS ((char *, struct file_name_list *,
+ const U_CHAR *, struct include_file **));
+static char *remap_include_file PARAMS ((char *, struct file_name_list *));
+static int lookup_ino_include PARAMS ((struct include_file *));
-static void finclude PROTO((int, struct include_file *, FILE_BUF *, int, struct file_name_list *));
-static void record_control_macro PROTO((struct include_file *, U_CHAR *));
+static void finclude PARAMS ((int, struct include_file *, FILE_BUF *, int,
+ struct file_name_list *));
+static void record_control_macro PARAMS ((struct include_file *,
+ const U_CHAR *));
-static char *check_precompiled PROTO((int, struct stat *, char *, char **));
-static int check_preconditions PROTO((char *));
-static void pcfinclude PROTO((U_CHAR *, U_CHAR *, FILE_BUF *));
-static void pcstring_used PROTO((HASHNODE *));
-static void write_output PROTO((void));
-static void pass_thru_directive PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *));
+static char *check_precompiled PARAMS ((int, struct stat *, const char *,
+ const char **));
+static int check_preconditions PARAMS ((const char *));
+static void pcfinclude PARAMS ((U_CHAR *, const U_CHAR *, FILE_BUF *));
+static void pcstring_used PARAMS ((HASHNODE *));
+static void write_output PARAMS ((void));
+static void pass_thru_directive PARAMS ((const U_CHAR *, const U_CHAR *,
+ FILE_BUF *, struct directive *));
-static MACRODEF create_definition PROTO((U_CHAR *, U_CHAR *, FILE_BUF *));
+static MACRODEF create_definition PARAMS ((const U_CHAR *, const U_CHAR *,
+ FILE_BUF *));
-static int check_macro_name PROTO((U_CHAR *, char *));
-static int compare_defs PROTO((DEFINITION *, DEFINITION *));
-static int comp_def_part PROTO((int, U_CHAR *, int, U_CHAR *, int, int));
+static int check_macro_name PARAMS ((const U_CHAR *, int));
+static int compare_defs PARAMS ((DEFINITION *, DEFINITION *));
+static int comp_def_part PARAMS ((int, const U_CHAR *, int, const U_CHAR *,
+ int, int));
-static DEFINITION *collect_expansion PROTO((U_CHAR *, U_CHAR *, int, struct arglist *));
+static DEFINITION *collect_expansion PARAMS ((const U_CHAR *, const U_CHAR *,
+ int, struct arglist *));
-int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
-static int compare_token_lists PROTO((struct arglist *, struct arglist *));
+int check_assertion PARAMS ((const U_CHAR *, int, int, struct arglist *));
+static int compare_token_lists PARAMS ((struct arglist *, struct arglist *));
-static struct arglist *read_token_list PROTO((U_CHAR **, U_CHAR *, int *));
-static void free_token_list PROTO((struct arglist *));
+static struct arglist *read_token_list PARAMS ((const U_CHAR **,
+ const U_CHAR *, int *));
+static void free_token_list PARAMS ((struct arglist *));
-static ASSERTION_HASHNODE *assertion_install PROTO((U_CHAR *, int, int));
-static ASSERTION_HASHNODE *assertion_lookup PROTO((U_CHAR *, int, int));
-static void delete_assertion PROTO((ASSERTION_HASHNODE *));
+static ASSERTION_HASHNODE *assertion_install PARAMS ((const U_CHAR *, int, int));
+static ASSERTION_HASHNODE *assertion_lookup PARAMS ((const U_CHAR *, int, int));
+static void delete_assertion PARAMS ((ASSERTION_HASHNODE *));
-static void do_once PROTO((void));
+static void do_once PARAMS ((void));
-static HOST_WIDE_INT eval_if_expression PROTO((U_CHAR *, int));
-static void conditional_skip PROTO((FILE_BUF *, int, enum node_type, U_CHAR *, FILE_BUF *));
-static void skip_if_group PROTO((FILE_BUF *, int, FILE_BUF *));
-static void validate_else PROTO((U_CHAR *, U_CHAR *));
+static HOST_WIDEST_INT eval_if_expression PARAMS ((const U_CHAR *, int));
+static void conditional_skip PARAMS ((FILE_BUF *, int, enum node_type,
+ const U_CHAR *, FILE_BUF *));
+static void skip_if_group PARAMS ((FILE_BUF *, int, FILE_BUF *));
+static void validate_else PARAMS ((const U_CHAR *, const U_CHAR *));
-static U_CHAR *skip_to_end_of_comment PROTO((FILE_BUF *, int *, int));
-static U_CHAR *skip_quoted_string PROTO((U_CHAR *, U_CHAR *, int, int *, int *, int *));
-static char *quote_string PROTO((char *, char *, size_t));
-static U_CHAR *skip_paren_group PROTO((FILE_BUF *));
+static U_CHAR *skip_to_end_of_comment PARAMS ((FILE_BUF *, int *, int));
+static U_CHAR *skip_quoted_string PARAMS ((const U_CHAR *, const U_CHAR *,
+ int, int *, int *, int *));
+static char *quote_string PARAMS ((char *, const char *, size_t));
+static U_CHAR *skip_paren_group PARAMS ((FILE_BUF *));
/* Last arg to output_line_directive. */
enum file_change_code {same_file, enter_file, leave_file};
-static void output_line_directive PROTO((FILE_BUF *, FILE_BUF *, int, enum file_change_code));
+static void output_line_directive PARAMS ((FILE_BUF *, FILE_BUF *, int, enum file_change_code));
-static void macroexpand PROTO((HASHNODE *, FILE_BUF *));
+static void macroexpand PARAMS ((HASHNODE *, FILE_BUF *));
struct argdata;
-static char *macarg PROTO((struct argdata *, int));
+static int macarg PARAMS ((struct argdata *, int));
-static U_CHAR *macarg1 PROTO((U_CHAR *, U_CHAR *, struct hashnode *, int *, int *, int *, int));
+static U_CHAR *macarg1 PARAMS ((U_CHAR *, const U_CHAR *, struct hashnode *, int *, int *, int *, int));
-static int discard_comments PROTO((U_CHAR *, int, int));
+static int discard_comments PARAMS ((U_CHAR *, int, int));
-static int change_newlines PROTO((U_CHAR *, int));
+static void change_newlines PARAMS ((struct argdata *));
-static char *my_strerror PROTO((int));
-void error PRINTF_PROTO_1((char *, ...));
-static void verror PROTO((char *, va_list));
-static void error_from_errno PROTO((char *));
-void warning PRINTF_PROTO_1((char *, ...));
-static void vwarning PROTO((char *, va_list));
-static void error_with_line PRINTF_PROTO_2((int, char *, ...));
-static void verror_with_line PROTO((int, char *, va_list));
-static void vwarning_with_line PROTO((int, char *, va_list));
-static void warning_with_line PRINTF_PROTO_2((int, char *, ...));
-void pedwarn PRINTF_PROTO_1((char *, ...));
-void pedwarn_with_line PRINTF_PROTO_2((int, char *, ...));
-static void pedwarn_with_file_and_line PRINTF_PROTO_4((char *, size_t, int, char *, ...));
+static void notice PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
+static void vnotice PARAMS ((const char *, va_list));
+void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void verror PARAMS ((const char *, va_list));
+static void error_from_errno PARAMS ((const char *));
+void warning PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
+static void vwarning PARAMS ((const char *, va_list));
+static void error_with_line PARAMS ((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
+static void verror_with_line PARAMS ((int, const char *, va_list));
+static void vwarning_with_line PARAMS ((int, const char *, va_list));
+static void warning_with_line PARAMS ((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
+void pedwarn PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void pedwarn_with_line PARAMS ((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
+static void pedwarn_with_file_and_line PARAMS ((const char *, size_t, int, const char *, ...)) ATTRIBUTE_PRINTF_4;
+static void pedwarn_strange_white_space PARAMS ((int));
-static void print_containing_files PROTO((void));
+static void print_containing_files PARAMS ((void));
-static int line_for_error PROTO((int));
-static int grow_outbuf PROTO((FILE_BUF *, int));
+static int line_for_error PARAMS ((int));
+static int grow_outbuf PARAMS ((FILE_BUF *, int));
-static HASHNODE *install PROTO((U_CHAR *, int, enum node_type, char *, int));
-HASHNODE *lookup PROTO((U_CHAR *, int, int));
-static void delete_macro PROTO((HASHNODE *));
-static int hashf PROTO((U_CHAR *, int, int));
+static HASHNODE *install PARAMS ((const U_CHAR *, int, enum node_type,
+ const char *, int));
+HASHNODE *lookup PARAMS ((const U_CHAR *, int, int));
+static void delete_macro PARAMS ((HASHNODE *));
+static int hashf PARAMS ((const U_CHAR *, int, int));
-static void dump_single_macro PROTO((HASHNODE *, FILE *));
-static void dump_all_macros PROTO((void));
-static void dump_defn_1 PROTO((U_CHAR *, int, int, FILE *));
-static void dump_arg_n PROTO((DEFINITION *, int, FILE *));
+static void dump_single_macro PARAMS ((HASHNODE *, FILE *));
+static void dump_all_macros PARAMS ((void));
+static void dump_defn_1 PARAMS ((const U_CHAR *, int, int, FILE *));
+static void dump_arg_n PARAMS ((DEFINITION *, int, FILE *));
-static void initialize_char_syntax PROTO((void));
-static void initialize_builtins PROTO((FILE_BUF *, FILE_BUF *));
+static void initialize_char_syntax PARAMS ((void));
+static void initialize_builtins PARAMS ((FILE_BUF *, FILE_BUF *));
-static void make_definition PROTO((char *));
-static void make_undef PROTO((char *, FILE_BUF *));
+static void make_definition PARAMS ((char *));
+static void make_undef PARAMS ((char *, FILE_BUF *));
-static void make_assertion PROTO((char *, char *));
+static void make_assertion PARAMS ((const char *, const char *));
-static struct file_name_list *new_include_prefix PROTO((struct file_name_list *, char *, char *, char *));
-static void append_include_chain PROTO((struct file_name_list *, struct file_name_list *));
+static struct file_name_list *new_include_prefix PARAMS ((struct file_name_list *, const char *, const char *, const char *));
+static void append_include_chain PARAMS ((struct file_name_list *, struct file_name_list *));
-static int quote_string_for_make PROTO((char *, char *));
-static void deps_output PROTO((char *, int));
+static int quote_string_for_make PARAMS ((char *, const char *));
+static void deps_output PARAMS ((const char *, int));
-static void fatal PRINTF_PROTO_1((char *, ...)) __attribute__ ((noreturn));
-void fancy_abort PROTO((void)) __attribute__ ((noreturn));
-static void perror_with_name PROTO((char *));
-static void pfatal_with_name PROTO((char *)) __attribute__ ((noreturn));
-static void pipe_closed PROTO((int)) __attribute__ ((noreturn));
+void fatal PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
+static void perror_with_name PARAMS ((const char *));
+static void pfatal_with_name PARAMS ((const char *)) ATTRIBUTE_NORETURN;
+static void pipe_closed PARAMS ((int)) ATTRIBUTE_NORETURN;
-static void memory_full PROTO((void)) __attribute__ ((noreturn));
-GENERIC_PTR xmalloc PROTO((size_t));
-static GENERIC_PTR xrealloc PROTO((GENERIC_PTR, size_t));
-static GENERIC_PTR xcalloc PROTO((size_t, size_t));
-static char *savestring PROTO((char *));
-static void print_help PROTO((void));
+static void memory_full PARAMS ((void)) ATTRIBUTE_NORETURN;
+static void print_help PARAMS ((void));
\f
/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
retrying if necessary. If MAX_READ_LEN is defined, read at most
static void
safe_write (desc, ptr, len)
int desc;
- char *ptr;
+ const char *ptr;
int len;
{
int wcount, written;
}
}
-/* Print a string to stderr, with extra handling in case it contains
- embedded NUL characters. Any present are written as is.
-
- Using fwrite for this purpose produces undesireable results on VMS
- when stderr happens to be a record oriented file, such as a batch log
- file, rather than a stream oriented one. */
-
-static void
-eprint_string (string, length)
- char *string;
- size_t length;
-{
- size_t segment_length;
-
- do {
- fprintf(stderr, "%s", string);
- length -= (segment_length = strlen(string));
- if (length > 0)
- {
- fputc('\0', stderr);
- length -= 1;
- /* Advance past the portion which has already been printed. */
- string += segment_length + 1;
- }
- } while (length > 0);
-}
-
\f
static void
print_help ()
printf ("Usage: %s [switches] input output\n", progname);
printf ("Switches:\n");
printf (" -include <file> Include the contents of <file> before other files\n");
- printf (" -imacros <file> Accept definition of marcos in <file>\n");
+ printf (" -imacros <file> Accept definition of macros in <file>\n");
printf (" -iprefix <path> Specify <path> as a prefix for next two options\n");
printf (" -iwithprefix <dir> Add <dir> to the end of the system include paths\n");
printf (" -iwithprefixbefore <dir> Add <dir> to the end of the main include paths\n");
printf (" -traditional Follow K&R pre-processor behaviour\n");
printf (" -trigraphs Support ANSI C trigraphs\n");
printf (" -lang-c Assume that the input sources are in C\n");
- printf (" -lang-c89 Assume that the input sources are in C89\n");
+ printf (" -lang-c89 Assume that the input is C89; depricated\n");
printf (" -lang-c++ Assume that the input sources are in C++\n");
printf (" -lang-objc Assume that the input sources are in ObjectiveC\n");
printf (" -lang-objc++ Assume that the input sources are in ObjectiveC++\n");
printf (" -lang-asm Assume that the input sources are in assembler\n");
+ printf (" -lang-fortran Assume that the input sources are in Fortran\n");
printf (" -lang-chill Assume that the input sources are in Chill\n");
+ printf (" -std=<std name> Specify the conformance standard; one of:\n");
+ printf (" gnu89, gnu99, c89, c99, iso9899:1990,\n");
+ printf (" iso9899:199409, iso9899:1999\n");
printf (" -+ Allow parsing of C++ style features\n");
printf (" -w Inhibit warning messages\n");
printf (" -Wtrigraphs Warn if trigraphs are encountered\n");
printf (" -Wcomment{s} Warn if one comment starts inside another\n");
printf (" -Wno-comment{s} Do not warn about comments\n");
printf (" -Wtraditional Warn if a macro argument is/would be turned into\n");
- printf (" a string if -tradtional is specified\n");
+ printf (" a string if -traditional is specified\n");
printf (" -Wno-traditional Do not warn about stringification\n");
printf (" -Wundef Warn if an undefined macro is used by #if\n");
- printf (" -Wno-undef Do not warn about testing udefined macros\n");
+ printf (" -Wno-undef Do not warn about testing undefined macros\n");
printf (" -Wimport Warn about the use of the #import directive\n");
printf (" -Wno-import Do not warn about the use of #import\n");
printf (" -Werror Treat all warnings as errors\n");
char **argv;
{
struct stat st;
- char *in_fname;
+ const char *in_fname;
char *cp;
int f, i;
FILE_BUF *fp;
- char **pend_files = (char **) xmalloc (argc * sizeof (char *));
- char **pend_defs = (char **) xmalloc (argc * sizeof (char *));
- char **pend_undefs = (char **) xmalloc (argc * sizeof (char *));
- char **pend_assertions = (char **) xmalloc (argc * sizeof (char *));
- char **pend_includes = (char **) xmalloc (argc * sizeof (char *));
+
+ char **pend_files;
+ char **pend_defs;
+ char **pend_undefs;
+ char **pend_assertions;
+ char **pend_includes;
/* Record the option used with each element of pend_assertions.
This is preparation for supporting more than one option for making
an assertion. */
- char **pend_assertion_options = (char **) xmalloc (argc * sizeof (char *));
- int inhibit_predefs = 0;
+ const char **pend_assertion_options;
int no_standard_includes = 0;
int no_standard_cplusplus_includes = 0;
int missing_newline = 0;
This is 0 if deps are being written to stdout. */
char *deps_file = 0;
/* Fopen file mode to open deps_file with. */
- char *deps_mode = "a";
+ const char *deps_mode = "a";
/* Stream on which to print the dependency information. */
FILE *deps_stream = 0;
/* Target-name to write with the dependency information. */
signal (SIGPIPE, pipe_closed);
#endif
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
progname = base_name (argv[0]);
#ifdef VMS
{
/* Remove extension from PROGNAME. */
char *p;
- char *s = progname = savestring (progname);
+ char *s = xstrdup (progname);
+ progname = s;
if ((p = rindex (s, ';')) != 0) *p = '\0'; /* strip version number */
if ((p = rindex (s, '.')) != 0 /* strip type iff ".exe" */
}
#endif
+ /* Do not invoke xmalloc before this point, since locale and
+ progname need to be set first, in case a diagnostic is issued. */
+
+ pend_files = (char **) xmalloc (argc * sizeof (char *));
+ pend_defs = (char **) xmalloc ((2 * argc) * sizeof (char *));
+ pend_undefs = (char **) xmalloc (argc * sizeof (char *));
+ pend_assertions = (char **) xmalloc (argc * sizeof (char *));
+ pend_includes = (char **) xmalloc (argc * sizeof (char *));
+ pend_assertion_options = (const char **) xmalloc (argc * sizeof (char *));
+
in_fname = NULL;
out_fname = NULL;
cplusplus_comments = 1;
bzero ((char *) pend_files, argc * sizeof (char *));
- bzero ((char *) pend_defs, argc * sizeof (char *));
+ bzero ((char *) pend_defs, (2 * argc) * sizeof (char *));
bzero ((char *) pend_undefs, argc * sizeof (char *));
bzero ((char *) pend_assertions, argc * sizeof (char *));
bzero ((char *) pend_includes, argc * sizeof (char *));
case 'i':
if (!strcmp (argv[i], "-include")) {
- int temp = i;
-
if (i + 1 == argc)
fatal ("Filename missing after `-include' option");
- else
- simplify_filename (pend_includes[temp] = argv[++i]);
+ else {
+ i++;
+ simplify_filename (pend_includes[i] = argv[i]);
+ }
}
if (!strcmp (argv[i], "-imacros")) {
- int temp = i;
-
if (i + 1 == argc)
fatal ("Filename missing after `-imacros' option");
- else
- simplify_filename (pend_files[temp] = argv[++i]);
+ else {
+ i++;
+ simplify_filename (pend_files[i] = argv[i]);
+ }
}
if (!strcmp (argv[i], "-iprefix")) {
if (i + 1 == argc)
if (include_prefix != 0)
prefix = include_prefix;
else {
- prefix = savestring (GCC_INCLUDE_DIR);
+ prefix = xstrdup (GCC_INCLUDE_DIR);
/* Remove the `include' from /usr/local/lib/gcc.../include. */
if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
prefix[strlen (prefix) - 7] = 0;
if (include_prefix != 0)
prefix = include_prefix;
else {
- prefix = savestring (GCC_INCLUDE_DIR);
+ prefix = xstrdup (GCC_INCLUDE_DIR);
/* Remove the `include' from /usr/local/lib/gcc.../include. */
if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
prefix[strlen (prefix) - 7] = 0;
case 'l':
if (! strcmp (argv[i], "-lang-c"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 0;
- if (! strcmp (argv[i], "-lang-c89"))
- cplusplus = 0, cplusplus_comments = 0, c89 = 1, objc = 0;
- if (! strcmp (argv[i], "-lang-c++"))
- cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 0;
- if (! strcmp (argv[i], "-lang-objc"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 1;
- if (! strcmp (argv[i], "-lang-objc++"))
- cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 1;
- if (! strcmp (argv[i], "-lang-asm"))
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, c99 = 1, objc = 0;
+ else if (! strcmp (argv[i], "-lang-c89"))
+ {
+ cplusplus = 0, cplusplus_comments = 0, c89 = 1, c99 = 0, objc = 0;
+ no_trigraphs = 0;
+ pend_defs[2*i] = "__STRICT_ANSI__";
+ }
+ else if (! strcmp (argv[i], "-lang-c++"))
+ cplusplus = 1, cplusplus_comments = 1, c89 = 0, c99 = 0, objc = 0;
+ else if (! strcmp (argv[i], "-lang-objc"))
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, c99 = 0, objc = 1;
+ else if (! strcmp (argv[i], "-lang-objc++"))
+ cplusplus = 1, cplusplus_comments = 1, c89 = 0, c99 = 0, objc = 1;
+ else if (! strcmp (argv[i], "-lang-asm"))
lang_asm = 1;
- if (! strcmp (argv[i], "-lint"))
+ else if (! strcmp (argv[i], "-lang-fortran"))
+ /* Doesn't actually do anything. */ ;
+ else if (! strcmp (argv[i], "-lint"))
for_lint = 1;
break;
cplusplus = 1, cplusplus_comments = 1;
break;
+ case 's':
+ if (!strcmp (argv[i], "-std=gnu89"))
+ {
+ cplusplus = 0, cplusplus_comments = 0, c89 = 1, c99 = 0, objc = 0;
+ }
+ else if (!strcmp (argv[i], "-std=gnu9x")
+ || !strcmp (argv[i], "-std=gnu99"))
+ {
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, c99 = 1, objc = 0;
+ pend_defs[2*i+1] = "__STDC_VERSION__=199901L";
+ }
+ else if (!strcmp (argv[i], "-std=iso9899:1990")
+ || !strcmp (argv[i], "-std=c89"))
+ {
+ cplusplus = 0, cplusplus_comments = 0, c89 = 1, c99 = 0, objc = 0;
+ no_trigraphs = 0;
+ pend_defs[2*i] = "__STRICT_ANSI__";
+ }
+ else if (!strcmp (argv[i], "-std=iso9899:199409"))
+ {
+ cplusplus = 0, cplusplus_comments = 0, c89 = 1, c99 = 0, objc = 0;
+ no_trigraphs = 0;
+ pend_defs[2*i] = "__STRICT_ANSI__";
+ pend_defs[2*i+1] = "__STDC_VERSION__=199409L";
+ }
+ else if (!strcmp (argv[i], "-std=iso9899:199x")
+ || !strcmp (argv[i], "-std=iso9899:1999")
+ || !strcmp (argv[i], "-std=c9x")
+ || !strcmp (argv[i], "-std=c99"))
+ {
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, c99 = 1, objc = 0;
+ no_trigraphs = 0;
+ pend_defs[2*i] = "__STRICT_ANSI__";
+ pend_defs[2*i+1] = "__STDC_VERSION__=199901L";
+ }
+ break;
+
case 'w':
inhibit_warnings = 1;
break;
warn_stringify = 1;
else if (!strcmp (argv[i], "-Wno-traditional"))
warn_stringify = 0;
+ else if (!strcmp (argv[i], "-Wwhite-space"))
+ warn_white_space = 1;
+ else if (!strcmp (argv[i], "-Wno-white-space"))
+ warn_white_space = 0;
else if (!strcmp (argv[i], "-Wundef"))
warn_undef = 1;
else if (!strcmp (argv[i], "-Wno-undef"))
{
warn_trigraphs = 1;
warn_comments = 1;
+ warn_white_space = 1;
}
break;
break;
case 'v':
- fprintf (stderr, "GNU CPP version %s", version_string);
+ notice ("GNU CPP version %s", version_string);
#ifdef TARGET_VERSION
TARGET_VERSION;
#endif
case 'D':
if (argv[i][2] != 0)
- pend_defs[i] = argv[i] + 2;
+ pend_defs[2*i] = argv[i] + 2;
else if (i + 1 == argc)
fatal ("Macro name missing after -D option");
else
- i++, pend_defs[i] = argv[i];
+ i++, pend_defs[2*i] = argv[i];
break;
case 'A':
on the command line. That way we can get rid of any
that were passed automatically in from GCC. */
int j;
- inhibit_predefs = 1;
for (j = 0; j < i; j++)
- pend_defs[j] = pend_assertions[j] = 0;
+ pend_defs[2*j] = pend_assertions[j] = 0;
} else {
pend_assertions[i] = p;
pend_assertion_options[i] = "-A";
case 'I': /* Add directory to path for includes. */
{
struct file_name_list *dirtmp;
+ char *dir = argv[i][2] ? argv[i] + 2 : argv[++i];
- if (! ignore_srcdir && !strcmp (argv[i] + 2, "-")) {
+ if (! ignore_srcdir && dir && !strcmp (dir, "-")) {
ignore_srcdir = 1;
/* Don't use any preceding -I directories for #include <...>. */
first_bracket_include = 0;
}
else {
- dirtmp = new_include_prefix (last_include, NULL_PTR, "",
- argv[i][2] ? argv[i] + 2 : argv[++i]);
+ dirtmp = new_include_prefix (last_include, NULL_PTR, "", dir);
append_include_chain (dirtmp, dirtmp);
}
}
remap = 1;
break;
- case 'u':
- /* Sun compiler passes undocumented switch "-undef".
- Let's assume it means to inhibit the predefined symbols. */
- inhibit_predefs = 1;
- break;
-
case '\0': /* JF handle '-' as file name meaning stdin or stdout */
if (in_fname == NULL) {
in_fname = "";
fp->nominal_fname_len = strlen (in_fname);
fp->lineno = 0;
- /* In C++, wchar_t is a distinct basic type, and we can expect
- __wchar_t to be defined by cc1plus. */
- if (cplusplus)
- wchar_type = "__wchar_t";
-
/* Install __LINE__, etc. Must follow initialize_char_syntax
and option processing. */
initialize_builtins (fp, &outbuf);
- /* Do standard #defines and assertions
- that identify system and machine type. */
-
- if (!inhibit_predefs) {
- char *p = (char *) alloca (strlen (predefs) + 1);
-
-#ifdef VMS
- struct dsc$descriptor_s lcl_name;
- struct item_list {
- unsigned short length; /* input length */
- unsigned short code; /* item code */
- unsigned long dptr; /* data ptr */
- unsigned long lptr; /* output length ptr */
- };
-
- unsigned long syi_length;
- char syi_data[16];
-
- struct item_list items[] = {
- { 16, SYI$_VERSION, 0, 0 },
- { 0, 0, 0, 0 }
- };
-
- items[0].dptr = (unsigned long)syi_data;
- items[0].lptr = (unsigned long)(&syi_length);
-
- if (SYS$GETSYIW (0, 0, 0, items, NULL, NULL, NULL, NULL) == SS$_NORMAL)
- {
- unsigned long vms_version_value;
- char *vers;
-
- vers = syi_data;
- vms_version_value = 0;
-
- if (*vers == 'V')
- vers++;
- if (ISDIGIT (*vers))
- {
- vms_version_value = (*vers - '0') * 10000000;
- }
- vers++;
- if (*vers == '.')
- {
- vers++;
- if (ISDIGIT (*vers))
- {
- vms_version_value += (*vers - '0') * 100000;
- }
- }
-
- if (vms_version_value > 0)
- {
- char versbuf[32];
-
- sprintf (versbuf, "__VMS_VER=%08ld", vms_version_value);
- if (debug_output)
- output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (versbuf);
- }
- }
-#endif
-
- strcpy (p, predefs);
- while (*p) {
- char *q;
- while (*p == ' ' || *p == '\t')
- p++;
- /* Handle -D options. */
- if (p[0] == '-' && p[1] == 'D') {
- q = &p[2];
- while (*p && *p != ' ' && *p != '\t')
- p++;
- if (*p != 0)
- *p++= 0;
- if (debug_output)
- output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (q);
- while (*p == ' ' || *p == '\t')
- p++;
- } else if (p[0] == '-' && p[1] == 'A') {
- /* Handle -A options (assertions). */
- char *assertion;
- char *past_name;
- char *value;
- char *past_value;
- char *termination;
- int save_char;
-
- assertion = &p[2];
- past_name = assertion;
- /* Locate end of name. */
- while (*past_name && *past_name != ' '
- && *past_name != '\t' && *past_name != '(')
- past_name++;
- /* Locate `(' at start of value. */
- value = past_name;
- while (*value && (*value == ' ' || *value == '\t'))
- value++;
- if (*value++ != '(')
- abort ();
- while (*value && (*value == ' ' || *value == '\t'))
- value++;
- past_value = value;
- /* Locate end of value. */
- while (*past_value && *past_value != ' '
- && *past_value != '\t' && *past_value != ')')
- past_value++;
- termination = past_value;
- while (*termination && (*termination == ' ' || *termination == '\t'))
- termination++;
- if (*termination++ != ')')
- abort ();
- if (*termination && *termination != ' ' && *termination != '\t')
- abort ();
- /* Temporarily null-terminate the value. */
- save_char = *termination;
- *termination = '\0';
- /* Install the assertion. */
- make_assertion ("-A", assertion);
- *termination = (char) save_char;
- p = termination;
- while (*p == ' ' || *p == '\t')
- p++;
- } else {
- abort ();
- }
- }
- }
-
/* Now handle the command line options. */
/* Do -U's, -D's and -A's in the order they were seen. */
output_line_directive (fp, &outbuf, 0, same_file);
make_undef (pend_undefs[i], &outbuf);
}
- if (pend_defs[i]) {
+ if (pend_defs[2*i]) {
if (debug_output)
output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (pend_defs[i]);
+ make_definition (pend_defs[2*i]);
+ }
+ if (pend_defs[2*i+1]) {
+ if (debug_output)
+ output_line_directive (fp, &outbuf, 0, same_file);
+ make_definition (pend_defs[2*i+1]);
}
if (pend_assertions[i])
make_assertion (pend_assertion_options[i], pend_assertions[i]);
if (c == PATH_SEPARATOR || !c) {
endp[-1] = 0;
include_defaults[num_dirs].fname
- = startp == endp ? "." : savestring (startp);
+ = startp == endp ? "." : xstrdup (startp);
endp[-1] = c;
include_defaults[num_dirs].component = 0;
include_defaults[num_dirs].cplusplus = cplusplus;
}
}
/* Put the usual defaults back in at the end. */
- bcopy ((char *) include_defaults_array,
- (char *) &include_defaults[num_dirs],
+ bcopy ((const PTR) include_defaults_array,
+ (PTR) &include_defaults[num_dirs],
sizeof (include_defaults_array));
}
}
if (!no_standard_includes) {
struct default_include *p = include_defaults;
char *specd_prefix = include_prefix;
- char *default_prefix = savestring (GCC_INCLUDE_DIR);
+ char *default_prefix = xstrdup (GCC_INCLUDE_DIR);
int default_len = 0;
/* Remove the `include' from /usr/local/lib/gcc.../include. */
if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
append_include_chain (new, new);
if (first_system_include == 0)
first_system_include = new;
+ p->included = 1;
}
}
}
append_include_chain (new, new);
if (first_system_include == 0)
first_system_include = new;
+ p->included = 1;
}
}
}
/* With -v, print the list of dirs to search. */
if (verbose) {
struct file_name_list *p;
- fprintf (stderr, "#include \"...\" search starts here:\n");
+ notice ("#include \"...\" search starts here:\n");
for (p = include; p; p = p->next) {
if (p == first_bracket_include)
- fprintf (stderr, "#include <...> search starts here:\n");
+ notice ("#include <...> search starts here:\n");
if (!p->fname[0])
fprintf (stderr, " .\n");
else if (!strcmp (p->fname, "/") || !strcmp (p->fname, "//"))
/* Omit trailing '/'. */
fprintf (stderr, " %.*s\n", (int) strlen (p->fname) - 1, p->fname);
}
- fprintf (stderr, "End of search list.\n");
+ notice ("End of search list.\n");
+ {
+ struct default_include * d;
+ notice ("The following default directories have been omitted from the search path:\n");
+ for (d = include_defaults; d->fname; d++)
+ if (! d->included)
+ fprintf (stderr, " %s\n", d->fname);
+ notice ("End of omitted list.\n");
+ }
}
/* -MG doesn't select the form of output and must be specified with one of
else
print_deps = 1;
- s = spec;
/* Find the space before the DEPS_TARGET, if there is one. */
- /* This should use index. (mrs) */
- while (*s != 0 && *s != ' ') s++;
- if (*s != 0) {
+ s = index (spec, ' ');
+ if (s) {
deps_target = s + 1;
output_file = xmalloc (s - spec + 1);
bcopy (spec, output_file, s - spec);
output_file[s - spec] = 0;
- }
- else {
+ } else {
deps_target = 0;
output_file = spec;
}
strcpy (q, OBJECT_SUFFIX);
deps_output (p, ':');
- deps_output (in_fname, ' ');
}
+
+ deps_output (in_fname, ' ');
}
/* Scan the -imacros files before the main input.
if (!no_trigraphs)
trigraph_pcp (fp);
+ if (warn_white_space)
+ check_white_space (fp);
+
/* Now that we know the input file is valid, open the output. */
if (!out_fname || !strcmp (out_fname, ""))
If we knew we could use memchr, we could just invoke memchr (S, C, N),
but unfortunately memchr isn't autoconfigured yet. */
-static U_CHAR *
+static const U_CHAR *
index0 (s, c, n)
- U_CHAR *s;
+ const U_CHAR *s;
int c;
size_t n;
{
- char *p = (char *) s;
+ const char *p = (const char *) s;
for (;;) {
- char *q = index (p, c);
+ const char *q = index (p, c);
if (q)
- return (U_CHAR *) q;
+ return (const U_CHAR *) q;
else {
size_t l = strlen (p);
if (l == n)
trigraph_pcp (buf)
FILE_BUF *buf;
{
- register U_CHAR c, *fptr, *bptr, *sptr, *lptr;
+ register U_CHAR c, *bptr;
+ register const U_CHAR *fptr, *sptr, *lptr;
int len;
- fptr = bptr = sptr = buf->buf;
+ fptr = sptr = bptr = buf->buf;
lptr = fptr + buf->length;
while ((sptr = index0 (sptr, '?', (size_t) (lptr - sptr))) != NULL) {
if (*++sptr != '?')
/* BSD doc says bcopy () works right for overlapping strings. In ANSI
C, this will be memmove (). */
if (bptr != fptr && len > 0)
- bcopy ((char *) fptr, (char *) bptr, len);
+ bcopy ((const PTR) fptr, (PTR) bptr, len);
bptr += len;
*bptr++ = c;
}
len = buf->length - (fptr - buf->buf);
if (bptr != fptr && len > 0)
- bcopy ((char *) fptr, (char *) bptr, len);
+ bcopy ((const PTR) fptr, (PTR) bptr, len);
buf->length -= fptr - bptr;
buf->buf[buf->length] = '\0';
if (warn_trigraphs && fptr != bptr)
warning_with_line (0, "%lu trigraph(s) encountered",
(unsigned long) (fptr - bptr) / 2);
}
+
+/* Warn about white space between backslash and end of line. */
+
+static void
+check_white_space (buf)
+ FILE_BUF *buf;
+{
+ register const U_CHAR *sptr = buf->buf;
+ register const U_CHAR *lptr = sptr + buf->length;
+ register const U_CHAR *nptr;
+ int line = 0;
+
+ nptr = sptr = buf->buf;
+ lptr = sptr + buf->length;
+ for (nptr = sptr;
+ (nptr = index0 (nptr, '\n', (size_t) (lptr - nptr))) != NULL;
+ nptr ++) {
+ register const U_CHAR *p = nptr;
+ line++;
+ for (p = nptr; sptr < p; p--) {
+ if (! is_hor_space[p[-1]]) {
+ if (p[-1] == '\\' && p != nptr)
+ warning_with_line (line,
+ "`\\' followed by white space at end of line");
+ break;
+ }
+ }
+ }
+}
\f
/* Move all backslash-newline pairs out of embarrassing places.
Exchange all such pairs following BP
with any potentially-embarrassing characters that follow them.
Potentially-embarrassing characters are / and *
(because a backslash-newline inside a comment delimiter
- would cause it not to be recognized). */
+ would cause it not to be recognized).
+ We assume that *BP == '\\'. */
static void
newline_fix (bp)
register U_CHAR *p = bp;
/* First count the backslash-newline pairs here. */
-
- while (p[0] == '\\' && p[1] == '\n')
+ do {
+ if (p[1] != '\n')
+ break;
p += 2;
+ } while (*p == '\\');
/* What follows the backslash-newlines is not embarrassing. */
if (*p != '/' && *p != '*')
+ /* What follows the backslash-newlines is not embarrassing. */
return;
/* Copy all potentially embarrassing characters
that follow the backslash-newline pairs
down to where the pairs originally started. */
-
- while (*p == '*' || *p == '/')
+ do
*bp++ = *p++;
+ while (*p == '*' || *p == '/');
/* Now write the same number of pairs after the embarrassing chars. */
while (bp < p) {
register U_CHAR *p = bp;
/* First count the backslash-newline pairs here. */
- while (p[0] == '\\' && p[1] == '\n')
+ do {
+ if (p[1] != '\n')
+ break;
p += 2;
+ } while (*p == '\\');
/* What follows the backslash-newlines is not embarrassing. */
if (!is_idchar[*p])
+ /* What follows the backslash-newlines is not embarrassing. */
return;
/* Copy all potentially embarrassing characters
that follow the backslash-newline pairs
down to where the pairs originally started. */
-
- while (is_idchar[*p])
+ do
*bp++ = *p++;
+ while (is_idchar[*p]);
/* Now write the same number of pairs after the embarrassing chars. */
while (bp < p) {
arglen long. Note that we don't parse that arg since it will just
be printed out again. */
-static char *
+static const char *
get_lintcmd (ibp, limit, argstart, arglen, cmdlen)
- register U_CHAR *ibp;
- register U_CHAR *limit;
- U_CHAR **argstart; /* point to command arg */
+ register const U_CHAR *ibp;
+ register const U_CHAR *limit;
+ const U_CHAR **argstart; /* point to command arg */
int *arglen, *cmdlen; /* how long they are */
{
- HOST_WIDE_INT linsize;
- register U_CHAR *numptr; /* temp for arg parsing */
+ HOST_WIDEST_INT linsize;
+ register const U_CHAR *numptr; /* temp for arg parsing */
*arglen = 0;
* If OUTPUT_MARKS is nonzero, keep Newline markers found in the input
* and insert them when appropriate. This is set while scanning macro
* arguments before substitution. It is zero when scanning for final output.
- * There are three types of Newline markers:
+ * There are two types of Newline markers:
* * Newline - follows a macro name that was not expanded
* because it appeared inside an expansion of the same macro.
* This marker prevents future expansion of that identifier.
if (*ibp == '(') {
ip->bufp = ibp;
skip_paren_group (ip);
- bcopy ((char *) ibp, (char *) obp, ip->bufp - ibp);
+ bcopy ((const PTR) ibp, (PTR) obp, ip->bufp - ibp);
obp += ip->bufp - ibp;
ibp = ip->bufp;
}
*obp++ = *ibp;
switch (*ibp++) {
case '\n':
+ if (warn_white_space && ip->fname && is_hor_space[ibp[-2]])
+ warning ("white space at end of line in string");
++ip->lineno;
++op->lineno;
/* Traditionally, end of line ends a string constant with no error.
keep the line counts correct. But if we are reading
from a macro, keep the backslash newline, since backslash
newlines have already been processed. */
- if (ip->macro)
+ if (ip->macro) {
*obp++ = '\n';
- else
+ ++op->lineno;
+ } else
--obp;
++ibp;
++ip->lineno;
is *not* prevented from combining with a newline. */
if (!ip->macro) {
while (*ibp == '\\' && ibp[1] == '\n') {
- ibp += 2;
+ *obp++ = *ibp++;
+ *obp++ = *ibp++;
++ip->lineno;
+ ++op->lineno;
}
}
*obp++ = *ibp++;
case '/':
if (ip->macro != 0)
goto randomchar;
- if (*ibp == '\\' && ibp[1] == '\n')
+ if (*ibp == '\\')
newline_fix (ibp);
if (*ibp != '*'
&& !(cplusplus_comments && *ibp == '/'))
if (*ibp == '\n')
{
if (put_out_comments) {
- bcopy ((char *) before_bp, (char *) obp, ibp - before_bp);
+ bcopy ((const PTR) before_bp, (PTR) obp, ibp - before_bp);
obp += ibp - before_bp;
}
break;
/* If this cpp is for lint, we peek inside the comments: */
if (for_lint) {
- U_CHAR *argbp;
+ const U_CHAR *argbp;
int cmdlen, arglen;
- char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen);
+ const char *lintcmd =
+ get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen);
if (lintcmd != NULL) {
op->bufp = obp;
case '*':
if (ibp[-2] == '/' && warn_comments)
warning ("`/*' within comment");
- if (*ibp == '\\' && ibp[1] == '\n')
+ if (*ibp == '\\')
newline_fix (ibp);
if (*ibp == '/')
goto comment_end;
ibp++;
if (put_out_comments) {
- bcopy ((char *) before_bp, (char *) obp, ibp - before_bp);
+ bcopy ((const PTR) before_bp, (PTR) obp, ibp - before_bp);
obp += ibp - before_bp;
}
}
#endif
if (output_marks) {
+ op->bufp = obp;
check_expand (op, limit - ibp + 2);
+ obp = op->bufp;
*obp++ = '\n';
*obp++ = '-';
}
break;
else if (*ibp == '/') {
/* If a comment, copy it unchanged or discard it. */
- if (ibp[1] == '\\' && ibp[2] == '\n')
+ if (ibp[1] == '\\')
newline_fix (ibp + 1);
if (ibp[1] == '*') {
if (put_out_comments) {
/* We need not worry about newline-marks,
since they are never found in comments. */
if (ibp[0] == '*') {
- if (ibp[1] == '\\' && ibp[2] == '\n')
+ if (ibp[1] == '\\')
newline_fix (ibp + 1);
if (ibp[1] == '/') {
ibp += 2;
ending:
if (if_stack != ip->if_stack)
{
- char *str;
+ const char *str;
switch (if_stack->type)
{
*/
static FILE_BUF
expand_to_temp_buffer (buf, limit, output_marks, assertions)
- U_CHAR *buf, *limit;
+ const U_CHAR *buf;
+ const U_CHAR *limit;
int output_marks, assertions;
{
register FILE_BUF *ip;
buf1 = (U_CHAR *) alloca (length + 1);
{
- register U_CHAR *p1 = buf;
+ register const U_CHAR *p1 = buf;
register U_CHAR *p2 = buf1;
while (p1 != limit)
if (indepth != odepth)
abort ();
- /* Record the output. */
- obuf.length = obuf.bufp - obuf.buf;
-
assertions_flag = save_assertions_flag;
return obuf;
}
/* Record where the directive started. do_xifdef needs this. */
directive_start = bp - 1;
+ ignore_escape_flag = 1;
+
/* Skip whitespace and \-newline. */
while (1) {
if (is_hor_space[*bp]) {
if (*bp != ' ' && *bp != '\t' && pedantic)
- pedwarn ("%s in preprocessing directive", char_name[*bp]);
+ pedwarn_strange_white_space (*bp);
bp++;
} else if (*bp == '/') {
- if (bp[1] == '\\' && bp[2] == '\n')
+ if (bp[1] == '\\')
newline_fix (bp + 1);
if (! (bp[1] == '*' || (cplusplus_comments && bp[1] == '/')))
break;
if (is_idchar[*cp])
cp++;
else {
- if (*cp == '\\' && cp[1] == '\n')
+ if (*cp == '\\')
name_newline_fix (cp);
if (is_idchar[*cp])
cp++;
pedwarn ("`#' followed by integer");
after_ident = ident;
kt = line_directive_table;
+ ignore_escape_flag = 0;
goto old_linenum;
}
keep_comments = traditional && kt->type == T_DEFINE;
/* #import is defined only in Objective C, or when on the NeXT. */
if (kt->type == T_IMPORT
- && !(objc || lookup ((U_CHAR *) "__NeXT__", -1, -1)))
+ && !(objc || lookup ((const U_CHAR *) "__NeXT__", -1, -1)))
break;
/* Find the end of this directive (first newline not backslashed
register U_CHAR c = *bp++;
switch (c) {
case '\\':
- if (bp < limit) {
- if (*bp == '\n') {
- ip->lineno++;
- copy_directive = 1;
- bp++;
- } else if (traditional)
- bp++;
- }
+ if (*bp == '\n') {
+ ip->lineno++;
+ copy_directive = 1;
+ bp++;
+ } else if (traditional && bp < limit)
+ bp++;
break;
case '"':
break;
case '/':
- if (*bp == '\\' && bp[1] == '\n')
+ if (*bp == '\\')
newline_fix (bp);
if (*bp == '*'
|| (cplusplus_comments && *bp == '/')) {
case '\r':
case '\v':
if (pedantic)
- pedwarn ("%s in preprocessing directive", char_name[c]);
+ pedwarn_strange_white_space (c);
break;
case '\n':
/* If a directive should be copied through, and -C was given,
pass it through before removing comments. */
if (!no_output && put_out_comments
- && (kt->type == T_DEFINE ? dump_macros == dump_definitions
+ && ((kt->type == T_DEFINE || kt->type == T_UNDEF)
+ ? dump_macros == dump_definitions
: IS_INCLUDE_DIRECTIVE_TYPE (kt->type) ? dump_includes
: kt->type == T_PRAGMA)) {
int len;
register U_CHAR *xp = buf;
/* Need to copy entire directive into temp buffer before dispatching */
- cp = (U_CHAR *) alloca (bp - buf + 5); /* room for directive plus
- some slop */
+ /* room for directive plus some slop */
+ cp = (U_CHAR *) alloca (2 * (bp - buf) + 5);
buf = cp;
/* Copy to the new buffer, deleting comments
- and backslash-newlines (and whitespace surrounding the latter). */
+ and backslash-newlines (and whitespace surrounding the latter
+ if outside of char and string constants). */
while (xp < bp) {
register U_CHAR c = *xp++;
case '\'':
case '\"':
{
- register U_CHAR *bp1
+ int backslash_newlines_p = 0;
+
+ register const U_CHAR *bp1
= skip_quoted_string (xp - 1, bp, ip->lineno,
- NULL_PTR, NULL_PTR, NULL_PTR);
- while (xp != bp1)
- *cp++ = *xp++;
+ NULL_PTR, &backslash_newlines_p,
+ NULL_PTR);
+ if (backslash_newlines_p)
+ while (xp != bp1)
+ {
+ /* With something like:
+
+ #define X "a\
+ b"
+
+ we should still remove the backslash-newline
+ pair as part of phase two. */
+ if (xp[0] == '\\' && xp[1] == '\n')
+ xp += 2;
+ else
+ *cp++ = *xp++;
+ }
+ else
+ /* This is the same as the loop above, but taking
+ advantage of the fact that we know there are no
+ backslash-newline pairs. */
+ while (xp != bp1)
+ *cp++ = *xp++;
}
break;
directives through. */
if (!no_output && already_output == 0
- && (kt->type == T_DEFINE ? (int) dump_names <= (int) dump_macros
+ && ((kt->type == T_DEFINE || kt->type == T_UNDEF)
+ ? (int) dump_names <= (int) dump_macros
: IS_INCLUDE_DIRECTIVE_TYPE (kt->type) ? dump_includes
: kt->type == T_PRAGMA)) {
int len;
bcopy (buf, (char *) op->bufp, len);
}
op->bufp += len;
- } /* Don't we need a newline or #line? */
+ }
/* Call the appropriate directive handler. buf now points to
either the appropriate place in the input buffer, or to
static struct tm *
timestamp ()
{
- static struct tm *timebuf;
- if (!timebuf) {
+ static struct tm tmbuf;
+ if (! tmbuf.tm_mday) {
time_t t = time ((time_t *) 0);
- timebuf = localtime (&t);
+ struct tm *tm = localtime (&t);
+ if (tm)
+ tmbuf = *tm;
+ else {
+ /* Use 0000-01-01 00:00:00 if local time is not available. */
+ tmbuf.tm_year = -1900;
+ tmbuf.tm_mday = 1;
+ }
}
- return timebuf;
+ return &tmbuf;
}
-static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- };
+static const char * const monthnames[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+};
/*
* expand things like __FILE__. Place the expansion into the output
HASHNODE *hp;
FILE_BUF *op;
{
- char *buf;
+ const char *buf;
int i, len;
int true_indepth;
FILE_BUF *ip = NULL;
case T_BASE_FILE:
{
FILE_BUF *p = hp->type == T_FILE ? ip : &instack[0];
- char *string = p->nominal_fname;
+ const char *string = p->nominal_fname;
if (string)
{
size_t string_len = p->nominal_fname_len;
- buf = (char *) alloca (3 + 4 * string_len);
- quote_string (buf, string, string_len);
+ char *newbuf = (char *) alloca (3 + 4 * string_len);
+ quote_string (newbuf, string, string_len);
+ buf = newbuf;
}
else
buf = "\"\"";
}
case T_INCLUDE_LEVEL:
- true_indepth = 0;
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL)
- true_indepth++;
-
- buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */
- sprintf (buf, "%d", true_indepth - 1);
+ {
+ /* Eight bytes ought to be more than enough */
+ char *newbuf = (char *) alloca (8);
+ true_indepth = 0;
+ for (i = indepth; i >= 0; i--)
+ if (instack[i].fname != NULL)
+ true_indepth++;
+ sprintf (newbuf, "%d", true_indepth - 1);
+ buf = newbuf;
+ }
break;
case T_VERSION:
- buf = (char *) alloca (3 + strlen (version_string));
- sprintf (buf, "\"%s\"", version_string);
+ {
+ char *newbuf = (char *) alloca (3 + strlen (version_string));
+ sprintf (newbuf, "\"%s\"", version_string);
+ buf = newbuf;
+ }
break;
#ifndef NO_BUILTIN_SIZE_TYPE
break;
#endif
+#ifndef NO_BUILTIN_WCHAR_TYPE
case T_WCHAR_TYPE:
buf = wchar_type;
break;
+#endif
case T_USER_LABEL_PREFIX_TYPE:
buf = user_label_prefix;
#ifdef STDC_0_IN_SYSTEM_HEADERS
if (ip->system_header_p
&& hp->length == 8 && bcmp (hp->name, "__STDC__", 8) == 0
- && !lookup ((U_CHAR *) "__STRICT_ANSI__", -1, -1))
+ && !lookup ((const U_CHAR *) "__STRICT_ANSI__", -1, -1))
buf = "0";
#endif
if (pcp_inside_if && pcp_outfile)
break;
case T_SPECLINE:
- buf = (char *) alloca (10);
- sprintf (buf, "%d", ip->lineno);
+ {
+ char *newbuf = (char *) alloca (10);
+ sprintf (newbuf, "%d", ip->lineno);
+ buf = newbuf;
+ }
break;
case T_DATE:
case T_TIME:
- buf = (char *) alloca (20);
- timebuf = timestamp ();
- if (hp->type == T_DATE)
- sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
- timebuf->tm_mday, timebuf->tm_year + 1900);
- else
- sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
- timebuf->tm_sec);
+ {
+ char *newbuf = (char *) alloca (20);
+ timebuf = timestamp ();
+ if (hp->type == T_DATE)
+ sprintf (newbuf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
+ timebuf->tm_mday, timebuf->tm_year + 1900);
+ else
+ sprintf (newbuf, "\"%02d:%02d:%02d\"", timebuf->tm_hour,
+ timebuf->tm_min, timebuf->tm_sec);
+ buf = newbuf;
+ }
break;
case T_SPEC_DEFINED:
|| (hp->type == T_MACRO && hp->value.defn->predefined)))
/* Output a precondition for this macro use. */
fprintf (pcp_outfile, "#define %s\n", hp->name);
- buf = " 1 ";
+ if (hp->type == T_POISON) {
+ error("attempt to use poisoned `%s'.", hp->name);
+ buf = " 0 ";
+ } else {
+ buf = " 1 ";
+ }
}
else
if (pcp_outfile && pcp_inside_if) {
}
break;
+ case T_POISON:
+ error("attempt to use poisoned `%s'.", hp->name);
+ buf = " 0 "; /* Consider poisoned symbol to not be defined */
+ break;
+
oops:
error ("`defined' without an identifier");
FILE_BUF *op;
struct directive *keyword;
{
- U_CHAR *importing = keyword->type == T_IMPORT ? (U_CHAR *) "" : (U_CHAR *) 0;
+ const U_CHAR *importing =
+ keyword->type == T_IMPORT ? (const U_CHAR *) "" : (const U_CHAR *) 0;
int skip_dirs = (keyword->type == T_INCLUDE_NEXT);
static int import_warning = 0;
char *fname; /* Dynamically allocated fname buffer */
#endif
int pcf = -1;
char *pcfbuf;
- char *pcfbuflimit;
+ const char *pcfbuflimit;
int pcfnum;
if (pedantic && !instack[indepth].system_header_p)
&& !instack[indepth].system_header_p && !import_warning) {
import_warning = 1;
warning ("using `#import' is not recommended");
- fprintf (stderr, "The fact that a certain header file need not be processed more than once\n");
- fprintf (stderr, "should be indicated in the header file, not where it is used.\n");
- fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n");
- fprintf (stderr, " #ifndef _FOO_H_INCLUDED\n");
- fprintf (stderr, " #define _FOO_H_INCLUDED\n");
- fprintf (stderr, " ... <real contents of file> ...\n");
- fprintf (stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n");
- fprintf (stderr, "Then users can use `#include' any number of times.\n");
- fprintf (stderr, "GNU C automatically avoids processing the file more than once\n");
- fprintf (stderr, "when it is equipped with such a conditional.\n");
+ notice ("The fact that a certain header file need not be processed more than once\n\
+should be indicated in the header file, not where it is used.\n\
+The best way to do this is with a conditional of this form:\n\
+\n\
+ #ifndef _FOO_H_INCLUDED\n\
+ #define _FOO_H_INCLUDED\n\
+ ... <real contents of file> ...\n\
+ #endif /* Not _FOO_H_INCLUDED */\n\
+\n\
+Then users can use `#include' any number of times.\n\
+GNU C automatically avoids processing the file more than once\n\
+when it is equipped with such a conditional.\n");
}
get_filename:
for (fp = &instack[indepth]; fp >= instack; fp--)
{
int n;
- char *nam;
- if ((nam = fp->nominal_fname) != NULL) {
+ if ((fp->nominal_fname) != NULL) {
+ char *nam;
/* Found a named file. Figure out dir of the file,
and put it in front of the search list. */
dsp = ((struct file_name_list *)
alloca (sizeof (struct file_name_list)
+ fp->nominal_fname_len));
- strcpy (dsp->fname, nam);
+ strcpy (dsp->fname, fp->nominal_fname);
simplify_filename (dsp->fname);
nam = base_name (dsp->fname);
*nam = 0;
/* Expand buffer and then remove any newline markers.
We can't just tell expand_to_temp_buffer to omit the markers,
since it would put extra spaces in include file names. */
- FILE_BUF trybuf;
U_CHAR *src;
int errors_before_expansion = errors;
+ FILE_BUF trybuf;
+
trybuf = expand_to_temp_buffer (buf, limit, 1, 0);
if (errors != errors_before_expansion) {
free (trybuf.buf);
case '\'':
case '\"':
{
- U_CHAR *src1 = skip_quoted_string (src - 1, trybuf.bufp, 0,
+ const U_CHAR *src1 = skip_quoted_string (src - 1, trybuf.bufp, 0,
NULL_PTR, NULL_PTR, NULL_PTR);
while (src != src1)
*limit++ = *src++;
/* Actually process the file */
if (pcfbuf) {
- pcfname = xmalloc (strlen (pcftry) + 1);
- strcpy (pcfname, pcftry);
+ pcfname = xstrdup (pcftry);
pcfinclude ((U_CHAR *) pcfbuf, (U_CHAR *) fname, op);
}
else
static int
is_system_include (filename)
- register char *filename;
+ register const char *filename;
{
struct file_name_list *searchptr;
static char *
base_name (fname)
- char *fname;
+ const char *fname;
{
- char *s = fname;
- char *p;
+ const char *s = fname;
+ const char *p;
#if defined (__MSDOS__) || defined (_WIN32)
if (ISALPHA (s[0]) && s[1] == ':') s += 2;
#endif
if ((p = rindex (s, ']'))) s = p + 1; /* Skip directory. */
if ((p = rindex (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir. */
if (s != fname)
- return s;
+ return (char *) s;
#endif
if ((p = rindex (s, '/'))) s = p + 1;
#ifdef DIR_SEPARATOR
if ((p = rindex (s, DIR_SEPARATOR))) s = p + 1;
#endif
- return s;
+ return (char *) s;
}
/* Yield nonzero if FILENAME is absolute (i.e. not relative). */
static int
absolute_filename (filename)
- char *filename;
+ const char *filename;
{
-#if defined (__MSDOS__) || (defined (_WIN32) && !defined (__CYGWIN32__))
+#if defined (__MSDOS__) \
+ || (defined (_WIN32) && !defined (__CYGWIN__) && !defined (_UWIN))
if (ISALPHA (filename[0]) && filename[1] == ':') filename += 2;
#endif
-#if defined (__CYGWIN32__)
+#if defined (__CYGWIN__)
/* At present, any path that begins with a drive spec is absolute. */
if (ISALPHA (filename[0]) && filename[1] == ':') return 1;
#endif
return 0;
}
+/* Returns whether or not a given character is a directory separator.
+ Used by simplify_filename. */
+static inline int is_dir_separator PARAMS ((int));
+
+static inline
+int
+is_dir_separator(ch)
+ char ch;
+{
+ return (ch == DIR_SEPARATOR)
+#if defined (DIR_SEPARATOR_2)
+ || (ch == DIR_SEPARATOR_2)
+#endif
+ ;
+}
+
/* Remove unnecessary characters from FILENAME in place,
to avoid unnecessary filename aliasing.
Return the length of the resulting string.
char *to0;
/* Remove redundant initial /s. */
- if (*from == '/') {
- *to++ = '/';
- if (*++from == '/') {
- if (*++from == '/') {
- /* 3 or more initial /s are equivalent to 1 /. */
- while (*++from == '/')
- continue;
- } else {
- /* On some hosts // differs from /; Posix allows this. */
- static int slashslash_vs_slash;
- if (slashslash_vs_slash == 0) {
- struct stat s1, s2;
- slashslash_vs_slash = ((stat ("/", &s1) == 0 && stat ("//", &s2) == 0
- && INO_T_EQ (s1.st_ino, s2.st_ino)
- && s1.st_dev == s2.st_dev)
- ? 1 : -1);
- }
- if (slashslash_vs_slash < 0)
- *to++ = '/';
- }
+ if (is_dir_separator (*from))
+ {
+ *to++ = DIR_SEPARATOR;
+ if (is_dir_separator (*++from))
+ {
+ if (is_dir_separator (*++from))
+ {
+ /* 3 or more initial /s are equivalent to 1 /. */
+ while (is_dir_separator (*++from))
+ continue;
+ }
+ else
+ {
+ /* On some hosts // differs from /; Posix allows this. */
+ *to++ = DIR_SEPARATOR;
+ }
+ }
}
- }
+
to0 = to;
- for (;;) {
+ for (;;)
+ {
#ifndef VMS
- if (from[0] == '.' && from[1] == '/')
- from += 2;
- else
+ if (from[0] == '.' && from[1] == '/')
+ from += 2;
+ else
#endif
- {
- /* Copy this component and trailing /, if any. */
- while ((*to++ = *from++) != '/') {
- if (!to[-1]) {
- /* Trim . component at end of nonempty name. */
- to -= filename <= to - 3 && to[-3] == '/' && to[-2] == '.';
-
- /* Trim unnecessary trailing /s. */
- while (to0 < --to && to[-1] == '/')
- continue;
-
- *to = 0;
- return to - filename;
- }
- }
- }
+ {
+ /* Copy this component and trailing DIR_SEPARATOR, if any. */
+ while (!is_dir_separator (*to++ = *from++))
+ {
+ if (!to[-1])
+ {
+ /* Trim . component at end of nonempty name. */
+ to -= filename <= to - 3 && to[-3] == DIR_SEPARATOR && to[-2] == '.';
+
+ /* Trim unnecessary trailing /s. */
+ while (to0 < --to && to[-1] == DIR_SEPARATOR)
+ continue;
+
+ *to = 0;
+ return to - filename;
+ }
+ }
+#if defined(DIR_SEPARATOR_2)
+ /* Simplify to one directory separator. */
+ to[-1] = DIR_SEPARATOR;
+#endif
+ }
/* Skip /s after a /. */
- while (*from == '/')
+ while (is_dir_separator (*from))
from++;
}
}
static struct file_name_map *
read_name_map (dirname)
- char *dirname;
+ const char *dirname;
{
/* This structure holds a linked list of file name maps, one per
directory. */
map_list_ptr = ((struct file_name_map_list *)
xmalloc (sizeof (struct file_name_map_list)));
- map_list_ptr->map_list_name = savestring (dirname);
+ map_list_ptr->map_list_name = xstrdup (dirname);
map_list_ptr->map_list_map = NULL;
dirlen = strlen (dirname);
open_include_file (filename, searchptr, importing, pinc)
char *filename;
struct file_name_list *searchptr;
- U_CHAR *importing;
+ const U_CHAR *importing;
struct include_file **pinc;
{
char *fname = remap ? remap_include_file (filename, searchptr) : filename;
struct file_name_list *searchptr;
{
register struct file_name_map *map;
- register char *from;
+ register const char *from;
if (searchptr)
{
if (!no_trigraphs)
trigraph_pcp (fp);
+ if (warn_white_space)
+ check_white_space (fp);
+
output_line_directive (fp, op, 0, enter_file);
rescan (op, 0);
static void
record_control_macro (inc, macro_name)
struct include_file *inc;
- U_CHAR *macro_name;
+ const U_CHAR *macro_name;
{
if (!inc->control_macro || inc->control_macro[0])
inc->control_macro = macro_name;
check_precompiled (pcf, st, fname, limit)
int pcf;
struct stat *st;
- char *fname ATTRIBUTE_UNUSED;
- char **limit;
+ const char *fname ATTRIBUTE_UNUSED;
+ const char **limit;
{
int length = 0;
char *buf;
static int
check_preconditions (prec)
- char *prec;
+ const char *prec;
{
MACRODEF mdef;
- char *lineend;
+ const char *lineend;
while (*prec) {
lineend = index (prec, '\n');
HASHNODE *hp;
prec += 6;
- mdef = create_definition ((U_CHAR *) prec, (U_CHAR *) lineend, NULL_PTR);
+ mdef = create_definition ((const U_CHAR *) prec,
+ (const U_CHAR *) lineend, NULL_PTR);
if (mdef.defn == 0)
abort ();
|| mdef.defn->expansion[1] != ' ')))
return 0;
} else if (!strncmp (prec, "undef", 5)) {
- char *name;
+ const char *name;
int len;
prec += 5;
prec++;
len = prec - name;
- if (lookup ((U_CHAR *) name, len, -1))
+ if (lookup ((const U_CHAR *) name, len, -1))
return 0;
} else {
error ("Bad format encountered while reading precompiled file");
static void
pcfinclude (buf, name, op)
- U_CHAR *buf, *name;
+ U_CHAR *buf;
+ const U_CHAR *name;
FILE_BUF *op;
{
FILE_BUF tmpbuf;
cp += 4 - ((size_t) cp & 3);
/* Now get the string. */
- str = (STRINGDEF *) (GENERIC_PTR) cp;
+ str = (STRINGDEF *) (PTR) cp;
string_start = cp += sizeof (STRINGDEF);
for (; *cp; cp++) /* skip the string */
tmpbuf = expand_to_temp_buffer (string_start, cp++, 0, 0);
/* Lineno is already set in the precompiled file */
str->contents = tmpbuf.buf;
- str->len = tmpbuf.length;
+ str->len = tmpbuf.bufp - tmpbuf.buf;
str->writeflag = 0;
str->filename = name;
str->output_mark = outbuf.bufp - outbuf.buf;
else
/* Otherwise, for each key, */
for (; nkeys--; free (tmpbuf.buf), cp = endofthiskey + 1) {
- KEYDEF *kp = (KEYDEF *) (GENERIC_PTR) cp;
+ KEYDEF *kp = (KEYDEF *) (PTR) cp;
HASHNODE *hp;
+ U_CHAR *bp;
/* It starts with a KEYDEF structure */
cp += sizeof (KEYDEF);
/* Expand the key, and enter it into the hash table. */
tmpbuf = expand_to_temp_buffer (cp, endofthiskey, 0, 0);
- tmpbuf.bufp = tmpbuf.buf;
+ bp = tmpbuf.buf;
- while (is_hor_space[*tmpbuf.bufp])
- tmpbuf.bufp++;
- if (!is_idstart[*tmpbuf.bufp]
- || tmpbuf.bufp == tmpbuf.buf + tmpbuf.length) {
+ while (is_hor_space[*bp])
+ bp++;
+ if (!is_idstart[*bp] || bp == tmpbuf.bufp) {
str->writeflag = 1;
continue;
}
- hp = lookup (tmpbuf.bufp, -1, -1);
+ hp = lookup (bp, -1, -1);
if (hp == NULL) {
kp->chain = 0;
- install (tmpbuf.bufp, -1, T_PCSTRING, (char *) kp, -1);
+ install (bp, -1, T_PCSTRING, (char *) kp, -1);
}
else if (hp->type == T_PCSTRING) {
kp->chain = hp->value.keydef;
if (next_string
&& cur_buf_loc - outbuf.buf == next_string->output_mark) {
if (next_string->writeflag) {
- len = 4 * strlen ((char *) next_string->filename) + 32;
+ len = 4 * strlen ((const char *) next_string->filename) + 32;
while (len > line_directive_len)
line_directive = xrealloc (line_directive,
line_directive_len *= 2);
sprintf (line_directive, "\n# %d ", next_string->lineno);
strcpy (quote_string (line_directive + strlen (line_directive),
- (char *) next_string->filename,
- strlen ((char *) next_string->filename)),
+ (const char *) next_string->filename,
+ strlen ((const char *) next_string->filename)),
"\n");
safe_write (fileno (stdout), line_directive, strlen (line_directive));
safe_write (fileno (stdout),
static void
pass_thru_directive (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
+ const U_CHAR *buf;
+ const U_CHAR *limit;
FILE_BUF *op;
struct directive *keyword;
{
- register unsigned keyword_length = keyword->length;
+ register int keyword_length = keyword->length;
check_expand (op, 1 + keyword_length + (limit - buf));
*op->bufp++ = '#';
op->bufp += keyword_length;
if (limit != buf && buf[0] != ' ')
*op->bufp++ = ' ';
- bcopy ((char *) buf, (char *) op->bufp, limit - buf);
+ bcopy ((const PTR) buf, (PTR) op->bufp, limit - buf);
op->bufp += (limit - buf);
#if 0
*op->bufp++ = '\n';
struct arglist {
struct arglist *next;
- U_CHAR *name;
+ const U_CHAR *name;
int length;
int argno;
char rest_args;
static MACRODEF
create_definition (buf, limit, op)
- U_CHAR *buf, *limit;
+ const U_CHAR *buf, *limit;
FILE_BUF *op;
{
- U_CHAR *bp; /* temp ptr into input buffer */
- U_CHAR *symname; /* remember where symbol name starts */
+ const U_CHAR *bp; /* temp ptr into input buffer */
+ const U_CHAR *symname; /* remember where symbol name starts */
int sym_length; /* and how long it is */
int line = instack[indepth].lineno;
- char *file = instack[indepth].nominal_fname;
+ const char *file = instack[indepth].nominal_fname;
size_t file_len = instack[indepth].nominal_fname_len;
int rest_args = 0;
bp++;
symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, "macro");
+ sym_length = check_macro_name (bp, 0);
bp += sym_length;
/* Lossage will occur if identifiers or control keywords are broken
rest_extension);
if (!is_idstart[*bp])
+ {
+ if (c99 && limit - bp > (long) REST_EXTENSION_LENGTH
+ && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
+ {
+ /* This is the ISO C 99 way to write macros with variable
+ number of arguments. */
+ rest_args = 1;
+ temp->rest_args = 1;
+ }
+ else
pedwarn ("invalid character in macro parameter name");
+ }
/* Find the end of the arg name. */
while (is_idchar[*bp]) {
break;
}
}
+ if (bp == temp->name && rest_args == 1)
+ {
+ /* This is the ISO C 99 style. */
+ temp->name = (U_CHAR *) va_args_name;
+ temp->length = VA_ARGS_NAME_LENGTH;
+ }
+ else
temp->length = bp - temp->name;
if (rest_args == 1)
bp += REST_EXTENSION_LENGTH;
bp++;
SKIP_WHITE_SPACE (bp);
/* A comma at this point can only be followed by an identifier. */
- if (!is_idstart[*bp]) {
+ if (!is_idstart[*bp]
+ && !(c99 && limit - bp > (long) REST_EXTENSION_LENGTH
+ && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)) {
error ("badly punctuated parameter list in `#define'");
goto nope;
}
for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
if (temp->length == otemp->length
- && bcmp (temp->name, otemp->name, temp->length) == 0) {
+ && bcmp (temp->name, otemp->name, temp->length) == 0)
+ {
error ("duplicate argument name `%.*s' in `#define'",
temp->length, temp->name);
goto nope;
}
+ if (rest_args == 0 && temp->length == VA_ARGS_NAME_LENGTH
+ && bcmp (temp->name, va_args_name, VA_ARGS_NAME_LENGTH) == 0)
+ {
+ error ("\
+reserved name `%s' used as argument name in `#define'", va_args_name);
+ goto nope;
+ }
}
}
{
int hashcode;
MACRODEF mdef;
+ enum node_type newtype = keyword->type == T_DEFINE ? T_MACRO : T_POISON;
/* If this is a precompiler run (with -pcp) pass thru #define directives. */
if (pcp_outfile && op)
/* Redefining a precompiled key is ok. */
if (hp->type == T_PCSTRING)
ok = 1;
+ /* Redefining a poisoned identifier is even worse than `not ok'. */
+ else if (hp->type == T_POISON)
+ ok = -1;
+ /* Poisoning anything else is not ok.
+ The poison should always come first. */
+ else if (newtype == T_POISON)
+ ok = 0;
/* Redefining a macro is ok if the definitions are the same. */
else if (hp->type == T_MACRO)
ok = ! compare_defs (mdef.defn, hp->value.defn);
/* Redefining a constant is ok with -D. */
else if (hp->type == T_CONST)
ok = ! done_initializing;
- /* Print the warning if it's not ok. */
- if (!ok) {
- /* If we are passing through #define and #undef directives, do
- that for this re-definition now. */
- if (debug_output && op)
- pass_thru_directive (buf, limit, op, keyword);
-
- pedwarn ("`%.*s' redefined", mdef.symlen, mdef.symnam);
- if (hp->type == T_MACRO)
- pedwarn_with_file_and_line (hp->value.defn->file,
- hp->value.defn->file_len,
- hp->value.defn->line,
- "this is the location of the previous definition");
- }
- /* Replace the old definition. */
- hp->type = T_MACRO;
- hp->value.defn = mdef.defn;
+
+ /* Print the warning or error if it's not ok. */
+ if (ok <= 0)
+ {
+ /* If we are passing through #define and #undef directives, do
+ that for this re-definition now. */
+ if (debug_output && op)
+ pass_thru_directive (buf, limit, op, keyword);
+
+ if (hp->type == T_POISON)
+ error ("redefining poisoned `%.*s'", mdef.symlen, mdef.symnam);
+ else
+ pedwarn ("`%.*s' redefined", mdef.symlen, mdef.symnam);
+ if (hp->type == T_MACRO)
+ pedwarn_with_file_and_line (hp->value.defn->file,
+ hp->value.defn->file_len,
+ hp->value.defn->line,
+ "this is the location of the previous definition");
+ }
+ if (hp->type != T_POISON)
+ {
+ /* Replace the old definition. */
+ hp->type = newtype;
+ hp->value.defn = mdef.defn;
+ }
} else {
/* If we are passing through #define and #undef directives, do
that for this new definition now. */
if (debug_output && op)
pass_thru_directive (buf, limit, op, keyword);
- install (mdef.symnam, mdef.symlen, T_MACRO,
+ install (mdef.symnam, mdef.symlen, newtype,
(char *) mdef.defn, hashcode);
}
}
}
\f
/* Check a purported macro name SYMNAME, and yield its length.
- USAGE is the kind of name this is intended for. */
+ ASSERTION is nonzero if this is really for an assertion name. */
static int
-check_macro_name (symname, usage)
- U_CHAR *symname;
- char *usage;
+check_macro_name (symname, assertion)
+ const U_CHAR *symname;
+ int assertion;
{
- U_CHAR *p;
+ const U_CHAR *p;
int sym_length;
for (p = symname; is_idchar[*p]; p++)
sym_length = p - symname;
if (sym_length == 0
|| (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
- error ("invalid %s name", usage);
+ {
+ if (assertion)
+ error ("invalid assertion name");
+ else
+ error ("invalid macro name");
+ }
else if (!is_idstart[*symname]
|| (sym_length == 7 && ! bcmp (symname, "defined", 7)))
- error ("invalid %s name `%.*s'", usage, sym_length, symname);
+ {
+ if (assertion)
+ error ("invalid assertion name `%.*s'", sym_length, symname);
+ else
+ error ("invalid macro name `%.*s'", sym_length, symname);
+ }
return sym_length;
}
static int
comp_def_part (first, beg1, len1, beg2, len2, last)
int first;
- U_CHAR *beg1, *beg2;
+ const U_CHAR *beg1, *beg2;
int len1, len2;
int last;
{
- register U_CHAR *end1 = beg1 + len1;
- register U_CHAR *end2 = beg2 + len2;
+ register const U_CHAR *end1 = beg1 + len1;
+ register const U_CHAR *end2 = beg2 + len2;
if (first) {
while (beg1 != end1 && is_space[*beg1]) beg1++;
while (beg2 != end2 && is_space[*beg2]) beg2++;
static DEFINITION *
collect_expansion (buf, end, nargs, arglist)
- U_CHAR *buf, *end;
+ const U_CHAR *buf;
+ const U_CHAR *end;
int nargs;
struct arglist *arglist;
{
DEFINITION *defn;
- register U_CHAR *p, *limit, *lastp, *exp_p;
+ register const U_CHAR *p;
+ register const U_CHAR *limit;
+ register U_CHAR *lastp, *exp_p;
struct reflist *endpat = NULL;
/* Pointer to first nonspace after last ## seen. */
- U_CHAR *concat = 0;
+ const U_CHAR *concat = 0;
/* Pointer to first nonspace after last single-# seen. */
- U_CHAR *stringify = 0;
+ const U_CHAR *stringify = 0;
/* How those tokens were spelled. */
enum sharp_token_type concat_sharp_token_type = NO_SHARP_TOKEN;
enum sharp_token_type stringify_sharp_token_type = NO_SHARP_TOKEN;
break;
case '\\':
- if (p < limit && expected_delimiter) {
+ if (expected_delimiter) {
/* In a string, backslash goes through
and makes next char ordinary. */
*exp_p++ = *p++;
case '%':
if (!expected_delimiter && *p == ':') {
/* %: is not a digraph if preceded by an odd number of '<'s. */
- U_CHAR *p0 = p - 1;
+ const U_CHAR *p0 = p - 1;
while (buf < p0 && p0[-1] == '<')
p0--;
if ((p - p0) & 1) {
/* Handle the start of a symbol. */
if (is_idchar[c] && nargs > 0) {
- U_CHAR *id_beg = p - 1;
+ const U_CHAR *id_beg = p - 1;
int id_len;
--exp_p;
tpat->argno = arg->argno;
tpat->nchars = exp_p - lastp;
{
- register U_CHAR *p1 = p;
+ register const U_CHAR *p1 = p;
SKIP_WHITE_SPACE (p1);
if (p1[0]=='#'
? p1[1]=='#'
/* If this was not a macro arg, copy it into the expansion. */
if (! skipped_arg) {
- register U_CHAR *lim1 = p;
+ register const U_CHAR *lim1 = p;
p = id_beg;
while (p != lim1)
*exp_p++ = *p++;
FILE_BUF *op ATTRIBUTE_UNUSED;
struct directive *keyword ATTRIBUTE_UNUSED;
{
- U_CHAR *bp; /* temp ptr into input buffer */
- U_CHAR *symname; /* remember where symbol name starts */
+ const U_CHAR *bp; /* temp ptr into input buffer */
+ const U_CHAR *symname; /* remember where symbol name starts */
int sym_length; /* and how long it is */
struct arglist *tokens = NULL;
bp++;
symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, "assertion");
+ sym_length = check_macro_name (bp, 1);
bp += sym_length;
/* #define doesn't do this, but we should. */
SKIP_WHITE_SPACE (bp);
FILE_BUF *op ATTRIBUTE_UNUSED;
struct directive *keyword ATTRIBUTE_UNUSED;
{
- U_CHAR *bp; /* temp ptr into input buffer */
- U_CHAR *symname; /* remember where symbol name starts */
+ const U_CHAR *bp; /* temp ptr into input buffer */
+ const U_CHAR *symname; /* remember where symbol name starts */
int sym_length; /* and how long it is */
struct arglist *tokens = NULL;
bp++;
symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, "assertion");
+ sym_length = check_macro_name (bp, 1);
bp += sym_length;
/* #define doesn't do this, but we should. */
SKIP_WHITE_SPACE (bp);
int
check_assertion (name, sym_length, tokens_specified, tokens)
- U_CHAR *name;
+ const U_CHAR *name;
int sym_length;
int tokens_specified;
struct arglist *tokens;
static struct arglist *
read_token_list (bpp, limit, error_flag)
- U_CHAR **bpp;
- U_CHAR *limit;
+ const U_CHAR **bpp;
+ const U_CHAR *limit;
int *error_flag;
{
struct arglist *token_ptrs = 0;
- U_CHAR *bp = *bpp;
+ const U_CHAR *bp = *bpp;
int depth = 1;
*error_flag = 0;
/* Loop over the assertion value tokens. */
while (depth > 0) {
struct arglist *temp;
+ U_CHAR *temp2;
int eofp = 0;
- U_CHAR *beg = bp;
+ const U_CHAR *beg = bp;
/* Find the end of the token. */
if (*bp == '(') {
bp++;
temp = (struct arglist *) xmalloc (sizeof (struct arglist));
- temp->name = (U_CHAR *) xmalloc (bp - beg + 1);
- bcopy ((char *) beg, (char *) temp->name, bp - beg);
- temp->name[bp - beg] = 0;
+ temp2 = (U_CHAR *) xmalloc (bp - beg + 1);
+ bcopy ((const PTR) beg, (PTR) temp2, bp - beg);
+ temp2[bp - beg] = 0;
+ temp->name = temp2;
temp->next = token_ptrs;
token_ptrs = temp;
temp->length = bp - beg;
{
while (tokens) {
struct arglist *next = tokens->next;
- free (tokens->name);
+ free ((PTR) tokens->name);
free (tokens);
tokens = next;
}
static ASSERTION_HASHNODE *
assertion_install (name, len, hash)
- U_CHAR *name;
+ const U_CHAR *name;
int len;
int hash;
{
register ASSERTION_HASHNODE *hp;
register int i, bucket;
- register U_CHAR *p, *q;
+ register U_CHAR *p;
+ register const U_CHAR *q;
i = sizeof (ASSERTION_HASHNODE) + len + 1;
hp = (ASSERTION_HASHNODE *) xmalloc (i);
static ASSERTION_HASHNODE *
assertion_lookup (name, len, hash)
- U_CHAR *name;
+ const U_CHAR *name;
int len;
int hash;
{
/* Point to macroexpanded line, which is null-terminated now. */
bp = tem.buf;
+ limit = tem.bufp;
SKIP_WHITE_SPACE (bp);
if (!ISDIGIT (*bp)) {
p = bp;
for (;;)
switch ((*p++ = *bp++)) {
- case '\0':
- error ("invalid format `#line' directive");
- return 0;
-
case '\\':
- {
- char *bpc = (char *) bp;
- HOST_WIDE_INT c = parse_escape (&bpc, (HOST_WIDE_INT) (U_CHAR) (-1));
- bp = (U_CHAR *) bpc;
- if (c < 0)
- p--;
- else
- p[-1] = c;
- }
+ if (! ignore_escape_flag)
+ {
+ char *bpc = (char *) bp;
+ HOST_WIDEST_INT c = parse_escape (&bpc, (HOST_WIDEST_INT) (U_CHAR) (-1));
+ bp = (U_CHAR *) bpc;
+ if (c < 0)
+ p--;
+ else
+ p[-1] = c;
+ }
break;
case '\"':
ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
ip->nominal_fname_len = hp->length = fname_length;
- bcopy (fname, hp->value.cpval, fname_length + 1);
+ bcopy (fname, ((char *) hp) + sizeof (HASHNODE), fname_length + 1);
}
} else if (*bp) {
error ("invalid format `#line' directive");
pass_thru_directive (buf, limit, op, keyword);
SKIP_WHITE_SPACE (buf);
- sym_length = check_macro_name (buf, "macro");
+ sym_length = check_macro_name (buf, 0);
while ((hp = lookup (buf, sym_length, -1)) != NULL) {
/* If we are generating additional info for debugging (with -g) we
need to pass through all effective #undef directives. */
if (debug_output && op)
pass_thru_directive (orig_buf, limit, op, keyword);
- if (hp->type != T_MACRO)
- warning ("undefining `%s'", hp->name);
- delete_macro (hp);
+ if (hp->type == T_POISON)
+ error ("cannot undefine poisoned `%s'", hp->name);
+ else {
+ if (hp->type != T_MACRO)
+ warning ("undefining `%s'", hp->name);
+ delete_macro (hp);
+ }
}
if (pedantic) {
return 0;
}
\f
+
/* Report an error detected by the program we are processing.
- Use the text of the line in the error message.
- (We use error because it prints the filename & line#.) */
+ Use the text of the line in the error message. */
static int
do_error (buf, limit, op, keyword)
U_CHAR *buf, *limit;
FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
+ struct directive *keyword;
{
int length = limit - buf;
U_CHAR *copy = (U_CHAR *) alloca (length + 1);
- bcopy ((char *) buf, (char *) copy, length);
+ bcopy ((const PTR) buf, (PTR) copy, length);
copy[length] = 0;
SKIP_WHITE_SPACE (copy);
- error ("#error %s", copy);
- return 0;
-}
-/* Report a warning detected by the program we are processing.
- Use the text of the line in the warning message, then continue.
- (We use error because it prints the filename & line#.) */
+ switch (keyword->type) {
+ case T_ERROR:
+ error ("#error %s", copy);
+ break;
-static int
-do_warning (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- int length = limit - buf;
- U_CHAR *copy = (U_CHAR *) alloca (length + 1);
- bcopy ((char *) buf, (char *) copy, length);
- copy[length] = 0;
- SKIP_WHITE_SPACE (copy);
+ case T_WARNING:
+ if (pedantic && !instack[indepth].system_header_p)
+ pedwarn ("ANSI C does not allow `#warning'");
+ warning ("#warning %s", copy);
+ break;
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#warning'");
+ default:
+ abort ();
+ }
- /* Use `pedwarn' not `warning', because #warning isn't in the C Standard;
- if -pedantic-errors is given, #warning should cause an error. */
- pedwarn ("#warning %s", copy);
return 0;
}
-
/* Remember the name of the current file being read from so that we can
avoid ever including it again. */
for (i = indepth; i >= 0; i--)
if (instack[i].inc) {
- record_control_macro (instack[i].inc, (U_CHAR *) "");
+ record_control_macro (instack[i].inc, (const U_CHAR *) "");
break;
}
}
check_expand (op, 7 + len);
bcopy ("#ident ", (char *) op->bufp, 7);
op->bufp += 7;
- bcopy ((char *) buf, (char *) op->bufp, len);
+ bcopy ((const PTR) buf, (PTR) op->bufp, len);
op->bufp += len;
free (buf);
static int
do_pragma (buf, limit, op, keyword)
- U_CHAR *buf, *limit ATTRIBUTE_UNUSED;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
+ U_CHAR *buf, *limit;
+ FILE_BUF *op;
+ struct directive *keyword;
{
SKIP_WHITE_SPACE (buf);
if (!strncmp ((char *) buf, "once", 4)) {
do_once ();
}
+ if (!strncmp ((char *) buf, "poison", 6)) {
+ /* Poison these symbols so that all subsequent usage produces an
+ error message. */
+ U_CHAR *p = buf + 6;
+
+ SKIP_WHITE_SPACE (p);
+ while (p < limit)
+ {
+ U_CHAR *end = p;
+
+ while (end < limit && is_idchar[*end])
+ end++;
+ if (end < limit && !is_space[*end])
+ {
+ error ("invalid #pragma poison");
+ return 0;
+ }
+ do_define(p, end, op, keyword);
+ p = end;
+ SKIP_WHITE_SPACE (p);
+ }
+ }
+
if (!strncmp ((char *) buf, "implementation", 14)) {
/* Be quiet about `#pragma implementation' for a file only if it hasn't
been included yet. */
return 0;
fname = p + 1;
- if ((p = (U_CHAR *) index ((char *) fname, '\"')))
- *p = '\0';
+ p = skip_quoted_string (p, limit, 0, NULL_PTR, NULL_PTR, NULL_PTR);
+ if (p[-1] == '"')
+ *--p = '\0';
for (h = 0; h < INCLUDE_HASHSIZE; h++) {
struct include_file *inc;
static int
do_sccs (buf, limit, op, keyword)
- U_CHAR *buf ATTRIBUTE_UNUSED, *limit ATTRIBUTE_UNUSED;
+ U_CHAR *buf ATTRIBUTE_UNUSED;
+ U_CHAR *limit ATTRIBUTE_UNUSED;
FILE_BUF *op ATTRIBUTE_UNUSED;
struct directive *keyword ATTRIBUTE_UNUSED;
{
FILE_BUF *op;
struct directive *keyword ATTRIBUTE_UNUSED;
{
- HOST_WIDE_INT value;
+ HOST_WIDEST_INT value;
FILE_BUF *ip = &instack[indepth];
value = eval_if_expression (buf, limit - buf);
FILE_BUF *op;
struct directive *keyword ATTRIBUTE_UNUSED;
{
- HOST_WIDE_INT value;
+ HOST_WIDEST_INT value;
FILE_BUF *ip = &instack[indepth];
if (if_stack == instack[indepth].if_stack) {
&& !bcmp (if_stack->fname, ip->nominal_fname,
if_stack->fname_len))) {
fprintf (stderr, ", file ");
- eprint_string (if_stack->fname, if_stack->fname_len);
+ fwrite (if_stack->fname, sizeof if_stack->fname[0],
+ if_stack->fname_len, stderr);
}
fprintf (stderr, ")\n");
}
/* Evaluate a #if expression in BUF, of length LENGTH, then parse the
result as a C expression and return the value as an int. */
-static HOST_WIDE_INT
+static HOST_WIDEST_INT
eval_if_expression (buf, length)
- U_CHAR *buf;
+ const U_CHAR *buf;
int length;
{
FILE_BUF temp_obuf;
HASHNODE *save_defined;
- HOST_WIDE_INT value;
+ HOST_WIDEST_INT value;
- save_defined = install ((U_CHAR *) "defined", -1, T_SPEC_DEFINED,
+ save_defined = install ((const U_CHAR *) "defined", -1, T_SPEC_DEFINED,
NULL_PTR, -1);
pcp_inside_if = 1;
temp_obuf = expand_to_temp_buffer (buf, buf + length, 0, 1);
pcp_inside_if = 0;
delete_macro (save_defined); /* clean up special symbol */
- temp_obuf.buf[temp_obuf.length] = '\n';
+ *temp_obuf.bufp = '\n';
value = parse_c_expression ((char *) temp_obuf.buf,
warn_undef && !instack[indepth].system_header_p);
if (end == buf) {
skip = (keyword->type == T_IFDEF);
if (! traditional)
- pedwarn (end == limit ? "`#%s' with no argument"
- : "`#%s' argument starts with punctuation",
- keyword->name);
+ {
+ if (end == limit)
+ pedwarn ("`#%s' with no argument", keyword->name);
+ else
+ pedwarn ("`#%s' argument starts with punctuation", keyword->name);
+ }
} else {
HASHNODE *hp;
}
}
+ if ((hp != NULL) && (hp->type == T_POISON)) {
+ error("attempt to use poisoned `%s'.", hp->name);
+ hp = NULL;
+ }
skip = (hp == NULL) ^ (keyword->type == T_IFNDEF);
if (start_of_file && !skip) {
control_macro = (U_CHAR *) xmalloc (end - buf + 1);
- bcopy ((char *) buf, (char *) control_macro, end - buf);
+ bcopy ((const PTR) buf, (PTR) control_macro, end - buf);
control_macro[end - buf] = 0;
}
}
FILE_BUF *ip;
int skip;
enum node_type type;
- U_CHAR *control_macro;
+ const U_CHAR *control_macro;
FILE_BUF *op;
{
IF_STACK_FRAME *temp;
int skipping_include_directive = 0;
if (output_conditionals && op != 0) {
- char *ptr = "#failed\n";
+ static const char * const ptr = "#failed\n";
int len = strlen (ptr);
if (op->bufp > op->buf && op->bufp[-1] != '\n')
while (bp < endb) {
switch (*bp++) {
case '/': /* possible comment */
- if (*bp == '\\' && bp[1] == '\n')
+ if (*bp == '\\')
newline_fix (bp);
if (*bp == '*'
|| (cplusplus_comments && *bp == '/')) {
else if (*bp == '\\' && bp[1] == '\n')
bp += 2;
else if (*bp == '/') {
- if (bp[1] == '\\' && bp[2] == '\n')
+ if (bp[1] == '\\')
newline_fix (bp + 1);
if (bp[1] == '*') {
for (bp += 2; ; bp++) {
else if (*bp == '*') {
if (bp[-1] == '/' && warn_comments)
warning ("`/*' within comment");
- if (bp[1] == '\\' && bp[2] == '\n')
+ if (bp[1] == '\\')
newline_fix (bp + 1);
if (bp[1] == '/')
break;
if (is_idchar[*bp])
bp++;
else {
- if (*bp == '\\' && bp[1] == '\n')
+ if (*bp == '\\')
name_newline_fix (bp);
if (is_idchar[*bp])
bp++;
done:
if (output_conditionals && op != 0) {
- char *ptr = "#endfailed\n";
+ static const char * const ptr = "#endfailed\n";
int len = strlen (ptr);
if (op->bufp > op->buf && op->bufp[-1] != '\n')
op->lineno++;
}
check_expand (op, beg_of_line - beg_of_group);
- bcopy ((char *) beg_of_group, (char *) op->bufp,
+ bcopy ((const PTR) beg_of_group, (PTR) op->bufp,
beg_of_line - beg_of_group);
op->bufp += beg_of_line - beg_of_group;
op->lineno += ip->lineno - beg_lineno;
&& !bcmp (if_stack->fname, ip->nominal_fname,
if_stack->fname_len))) {
fprintf (stderr, ", file ");
- eprint_string (if_stack->fname, if_stack->fname_len);
+ fwrite (if_stack->fname, sizeof if_stack->fname[0],
+ if_stack->fname_len, stderr);
}
fprintf (stderr, ")\n");
}
static void
validate_else (p, limit)
- register U_CHAR *p;
- register U_CHAR *limit;
+ register const U_CHAR *p;
+ register const U_CHAR *limit;
{
/* Advance P over whitespace and comments. */
while (1) {
case '*':
if (bp[-2] == '/' && !nowarn && warn_comments)
warning ("`/*' within comment");
- if (*bp == '\\' && bp[1] == '\n')
+ if (*bp == '\\')
newline_fix (bp);
if (*bp == '/') {
if (op)
The input stack state is not changed.
If COUNT_NEWLINES is nonzero, it points to an int to increment
- for each newline passed.
+ for each newline passed; also, warn about any white space
+ just before line end.
If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
if we pass a backslash-newline.
static U_CHAR *
skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp)
- register U_CHAR *bp;
- register U_CHAR *limit;
+ register const U_CHAR *bp;
+ register const U_CHAR *limit;
int start_line;
int *count_newlines;
int *backslash_newlines_p;
}
if (match == '\'') {
error_with_line (line_for_error (start_line),
- "unterminated string or character constant");
+ "unterminated character constant");
bp--;
if (eofp)
*eofp = 1;
break;
}
/* If not traditional, then allow newlines inside strings. */
- if (count_newlines)
+ if (count_newlines) {
+ if (warn_white_space && is_hor_space[bp[-2]])
+ warning ("white space at end of line in string");
++*count_newlines;
+ }
if (multiline_string_line == 0) {
if (pedantic)
pedwarn_with_line (line_for_error (start_line),
}
#endif
}
- return bp;
+ return (U_CHAR *) bp;
}
/* Place into DST a quoted string representing the string SRC.
static char *
quote_string (dst, src, srclen)
- char *dst, *src;
+ char *dst;
+ const char *src;
size_t srclen;
{
U_CHAR c;
- char *srclim = src + srclen;
+ const char *srclim = src + srclen;
*dst++ = '\"';
while (src != srclim)
check_expand (op, len + 1);
if (op->bufp > op->buf && op->bufp[-1] != '\n')
*op->bufp++ = '\n';
- bcopy ((char *) line_directive_buf, (char *) op->bufp, len);
+ bcopy ((const PTR) line_directive_buf, (PTR) op->bufp, len);
op->bufp += len;
op->lineno = ip->lineno;
}
/* This structure represents one parsed argument in a macro call.
`raw' points to the argument text as written (`raw_length' is its length).
`expanded' points to the argument's macro-expansion
- (its length is `expand_length').
- `stringified_length' is the length the argument would have
- if stringified.
+ (its length is `expand_length', and its allocated size is `expand_size').
+ `stringified_length_bound' is an upper bound on the length
+ the argument would have if stringified.
`use_count' is the number of times this macro arg is substituted
into the macro. If the actual use count exceeds 10,
the value stored is 10.
`free1' and `free2', if nonzero, point to blocks to be freed
- when the macro argument data is no longer needed. */
+ when the macro argument data is no longer needed.
+ `free_ptr', if nonzero, points to a value of instack[i].free_ptr
+ where the raw field points somewhere into this string. The purpose
+ of this is to hold onto instack[i].buf for macro arguments, even
+ when the element has been popped off the input stack.
+*/
struct argdata {
U_CHAR *raw, *expanded;
- int raw_length, expand_length;
- int stringified_length;
+ int raw_length, expand_length, expand_size;
+ int stringified_length_bound;
U_CHAR *free1, *free2;
- char newlines;
+ U_CHAR *free_ptr;
+ int newlines;
char use_count;
};
if (nargs >= 0) {
register int i;
struct argdata *args;
- char *parse_error = 0;
+ int parse_error = 0;
args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
for (i = 0; i < nargs; i++) {
args[i].raw = (U_CHAR *) "";
args[i].expanded = 0;
- args[i].raw_length = args[i].expand_length
- = args[i].stringified_length = 0;
+ args[i].raw_length = args[i].expand_length = args[i].expand_size
+ = args[i].stringified_length_bound = 0;
args[i].free1 = args[i].free2 = 0;
+ args[i].free_ptr = 0;
args[i].use_count = 0;
}
else
parse_error = macarg (NULL_PTR, 0);
if (parse_error) {
- error_with_line (line_for_error (start_line), parse_error);
+ error_with_line (line_for_error (start_line),
+ "unterminated macro call");
break;
}
i++;
/* If we got one arg but it was just whitespace, call that 0 args. */
if (i == 1) {
- register U_CHAR *bp = args[0].raw;
- register U_CHAR *lim = bp + args[0].raw_length;
+ register const U_CHAR *bp = args[0].raw;
+ register const U_CHAR *lim = bp + args[0].raw_length;
/* cpp.texi says for foo ( ) we provide one argument.
However, if foo wants just 0 arguments, treat this as 0. */
if (nargs == 0)
Also count number of times each arg is used. */
xbuf_len = defn->length;
for (ap = defn->pattern; ap != NULL; ap = ap->next) {
- if (ap->stringify)
- xbuf_len += args[ap->argno].stringified_length;
+ if (ap->stringify && args[ap->argno].stringified_length_bound == 0)
+ /* macarg is not called for omitted arguments, as a result
+ stringified_length_bound will be zero. We need to make
+ enough space for "". */
+ xbuf_len += 2;
+ else if (ap->stringify)
+ xbuf_len += args[ap->argno].stringified_length_bound;
else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional)
/* Add 4 for two newline-space markers to prevent
token concatenation. */
1, 0);
args[ap->argno].expanded = obuf.buf;
- args[ap->argno].expand_length = obuf.length;
+ args[ap->argno].expand_length = obuf.bufp - obuf.buf;
+ args[ap->argno].expand_size = obuf.length;
args[ap->argno].free2 = obuf.buf;
- }
+ xbuf_len += args[ap->argno].expand_length;
+ } else {
+ /* If the arg appears more than once, its later occurrences
+ may have newline turned into backslash-'n', which is a
+ factor of 2 expansion. */
+ xbuf_len += 2 * args[ap->argno].expand_length;
+ }
/* Add 4 for two newline-space markers to prevent
token concatenation. */
- xbuf_len += args[ap->argno].expand_length + 4;
+ xbuf_len += 4;
}
if (args[ap->argno].use_count < 10)
args[ap->argno].use_count++;
for (; i < arglen; i++) {
c = arg->raw[i];
- if (! in_string) {
- /* Special markers Newline Space
+ if (in_string) {
+ /* Generate nothing for backslash-newline in a string. */
+ if (c == '\\' && arg->raw[i + 1] == '\n') {
+ i++;
+ continue;
+ }
+ } else {
+ /* Special markers
generate nothing for a stringified argument. */
- if (c == '\n' && arg->raw[i+1] != '\n') {
+ if (c == '\n') {
i++;
continue;
}
/* Internal sequences of whitespace are replaced by one space
- except within an string or char token. */
- if (c == '\n' ? arg->raw[i+1] == '\n' : is_space[c]) {
- while (1) {
- /* Note that Newline Space does occur within whitespace
- sequences; consider it part of the sequence. */
- if (c == '\n' && is_space[arg->raw[i+1]])
- i += 2;
- else if (c != '\n' && is_space[c])
- i++;
- else break;
- c = arg->raw[i];
- }
+ except within a string or char token. */
+ if (is_space[c]) {
+ i++;
+ while (is_space[(c = arg->raw[i])])
+ /* Newline markers can occur within a whitespace sequence;
+ consider them part of the sequence. */
+ i += (c == '\n') + 1;
i--;
c = ' ';
}
in_string = c;
}
- /* Escape these chars */
- if (c == '\"' || (in_string && c == '\\'))
+ /* Escape double-quote, and backslashes in strings.
+ Newlines in strings are best escaped as \n, since
+ otherwise backslash-backslash-newline-newline is
+ mishandled. The C Standard doesn't allow newlines in
+ strings, so we can escape newlines as we please. */
+ if (c == '\"'
+ || (in_string
+ && (c == '\\'
+ || (c == '\n' ? (c = 'n', 1) : 0))))
xbuf[totlen++] = '\\';
/* We used to output e.g. \008 for control characters here,
but this doesn't conform to the C Standard.
if (!traditional)
xbuf[totlen++] = '\"'; /* insert ending quote */
} else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional) {
- U_CHAR *p1 = arg->raw;
- U_CHAR *l1 = p1 + arg->raw_length;
+ const U_CHAR *p1 = arg->raw;
+ const U_CHAR *l1 = p1 + arg->raw_length;
if (ap->raw_before != 0) {
while (p1 != l1 && is_space[*p1]) p1++;
while (p1 != l1 && is_idchar[*p1])
while (p1 != l1) {
if (is_space[l1[-1]]) l1--;
else if (l1[-1] == '-') {
- U_CHAR *p2 = l1 - 1;
+ const U_CHAR *p2 = l1 - 1;
/* If a `-' is preceded by an odd number of newlines then it
and the last newline are a no-reexpansion marker. */
while (p2 != p1 && p2[-1] == '\n') p2--;
}
}
- bcopy ((char *) p1, (char *) (xbuf + totlen), l1 - p1);
+ bcopy ((const PTR) p1, (PTR) (xbuf + totlen), l1 - p1);
totlen += l1 - p1;
if (!traditional && ap->raw_after == 0) {
/* Ordinary expanded use of the argument.
xbuf[totlen++] = '\n';
xbuf[totlen++] = ' ';
}
- bcopy ((char *) arg->expanded, (char *) (xbuf + totlen),
+ bcopy ((const PTR) arg->expanded, (PTR) (xbuf + totlen),
arg->expand_length);
totlen += arg->expand_length;
if (!traditional) {
/* Don't bother doing change_newlines for subsequent
uses of arg. */
arg->use_count = 1;
- arg->expand_length
- = change_newlines (arg->expanded, arg->expand_length);
+ change_newlines (arg);
}
}
xbuf_len = totlen;
for (i = 0; i < nargs; i++) {
+ if (args[i].free_ptr != 0) {
+ U_CHAR *buf = args[i].free_ptr;
+ int d;
+ for (d = indepth; d >= 0; --d) {
+ if (instack[d].buf == buf) {
+ instack[d].free_ptr = buf; /* Give ownership back to instack */
+ goto no_free;
+ }
+ }
+ free (buf); /* buf is not on the stack; must have been popped */
+ no_free:;
+ }
if (args[i].free1 != 0)
free (args[i].free1);
if (args[i].free2 != 0)
REST_ARGS is passed to macarg1 to make it absorb the rest of the args.
Return nonzero to indicate a syntax error. */
-static char *
+static int
macarg (argptr, rest_args)
register struct argdata *argptr;
int rest_args;
{
FILE_BUF *ip = &instack[indepth];
int paren = 0;
- int newlines = 0;
+ int lineno0 = ip->lineno;
int comments = 0;
- char *result = 0;
+ int result = 0;
/* Try to parse as much of the argument as exists at this
input stack level. */
U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length, ip->macro,
- &paren, &newlines, &comments, rest_args);
+ &paren, &ip->lineno, &comments, rest_args);
/* If we find the end of the argument at this level,
set up *ARGPTR to point at it in the input stack. */
- if (!(ip->fname != 0 && (newlines != 0 || comments != 0))
+ if (!(ip->fname != 0 && (ip->lineno != lineno0 || comments != 0))
&& bp != ip->buf + ip->length) {
if (argptr != 0) {
argptr->raw = ip->bufp;
argptr->raw_length = bp - ip->bufp;
- argptr->newlines = newlines;
+ argptr->newlines = ip->lineno - lineno0;
+ /* The next two statements transfer ownership of the the buffer
+ from ip to argptr. Note that the second statement ensures that
+ a given free_ptr is owned by at most one macro argument. */
+ argptr->free_ptr = ip->free_ptr;
+ ip->free_ptr = 0;
}
ip->bufp = bp;
} else {
Therefore, we must allocate a temporary buffer and copy
the macro argument into it. */
int bufsize = bp - ip->bufp;
- int extra = newlines;
+ int extra = ip->lineno - lineno0;
U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1);
int final_start = 0;
- bcopy ((char *) ip->bufp, (char *) buffer, bufsize);
+ bcopy ((const PTR) ip->bufp, (PTR) buffer, bufsize);
ip->bufp = bp;
- ip->lineno += newlines;
while (bp == ip->buf + ip->length) {
if (instack[indepth].macro == 0) {
- result = "unterminated macro call";
+ result = 1;
break;
}
ip->macro->type = T_MACRO;
if (ip->free_ptr)
free (ip->free_ptr);
ip = &instack[--indepth];
- newlines = 0;
+ lineno0 = ip->lineno;
comments = 0;
bp = macarg1 (ip->bufp, ip->buf + ip->length, ip->macro, &paren,
- &newlines, &comments, rest_args);
+ &ip->lineno, &comments, rest_args);
final_start = bufsize;
bufsize += bp - ip->bufp;
- extra += newlines;
+ extra += ip->lineno - lineno0;
buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1);
- bcopy ((char *) ip->bufp, (char *) (buffer + bufsize - (bp - ip->bufp)),
+ bcopy ((const PTR) ip->bufp, (PTR) (buffer + bufsize - (bp - ip->bufp)),
bp - ip->bufp);
ip->bufp = bp;
- ip->lineno += newlines;
}
/* Now, if arg is actually wanted, record its raw form,
argptr->raw = buffer;
argptr->raw_length = bufsize;
argptr->free1 = buffer;
- argptr->newlines = newlines;
- if ((newlines || comments) && ip->fname != 0)
+ argptr->newlines = ip->lineno - lineno0;
+ if ((argptr->newlines || comments) && ip->fname != 0)
argptr->raw_length
= final_start +
discard_comments (argptr->raw + final_start,
argptr->raw_length - final_start,
- newlines);
+ argptr->newlines);
argptr->raw[argptr->raw_length] = 0;
if (argptr->raw_length > bufsize + extra)
abort ();
All this info goes into *ARGPTR. */
if (argptr != 0) {
- register U_CHAR *buf, *lim;
+ register const U_CHAR *buf, *lim;
register int totlen;
buf = argptr->raw;
SKIP_ALL_WHITE_SPACE (buf);
else
#endif
- if (c == '\"' || c == '\\') /* escape these chars */
+ if (c == '\"' || c == '\\' || c == '\n') /* escape these chars */
totlen++;
}
- argptr->stringified_length = totlen;
+ argptr->stringified_length_bound = totlen;
}
return result;
}
static U_CHAR *
macarg1 (start, limit, macro, depthptr, newlines, comments, rest_args)
U_CHAR *start;
- register U_CHAR *limit;
+ register const U_CHAR *limit;
struct hashnode *macro;
int *depthptr, *newlines, *comments;
int rest_args;
case '/':
if (macro)
break;
- if (bp[1] == '\\' && bp[2] == '\n')
+ if (bp[1] == '\\')
newline_fix (bp + 1);
if (bp[1] == '*') {
*comments = 1;
else if (*bp == '*') {
if (bp[-1] == '/' && warn_comments)
warning ("`/*' within comment");
- if (bp[1] == '\\' && bp[2] == '\n')
+ if (bp[1] == '\\')
newline_fix (bp + 1);
if (bp[1] == '/') {
bp++;
case '\"':
{
int quotec;
- for (quotec = *bp++; bp + 1 < limit && *bp != quotec; bp++) {
+ for (quotec = *bp++; bp < limit && *bp != quotec; bp++) {
if (*bp == '\\') {
bp++;
if (*bp == '\n')
++*newlines;
- if (!macro) {
- while (*bp == '\\' && bp[1] == '\n') {
- bp += 2;
- ++*newlines;
- }
+ while (*bp == '\\' && bp[1] == '\n') {
+ bp += 2;
+ ++*newlines;
}
} else if (*bp == '\n') {
+ if (warn_white_space && is_hor_space[bp[-1]] && ! macro)
+ warning ("white space at end of line in string");
++*newlines;
if (quotec == '\'')
break;
break;
case '/':
- if (*ibp == '\\' && ibp[1] == '\n')
+ if (*ibp == '\\')
newline_fix (ibp);
/* Delete any comment. */
if (cplusplus_comments && ibp[0] == '/') {
obp[-1] = ' ';
while (++ibp < limit) {
if (ibp[0] == '*') {
- if (ibp[1] == '\\' && ibp[2] == '\n')
+ if (ibp[1] == '\\')
newline_fix (ibp + 1);
if (ibp[1] == '/') {
ibp += 2;
return obp - start;
}
\f
-/* Turn newlines to spaces in the string of length LENGTH at START,
- except inside of string constants.
- The string is copied into itself with its beginning staying fixed. */
+/* Turn newlines to spaces in the macro argument ARG.
+ Remove backslash-newline from string constants,
+ and turn other newlines in string constants to backslash-'n'. */
-static int
-change_newlines (start, length)
- U_CHAR *start;
- int length;
+static void
+change_newlines (arg)
+ struct argdata *arg;
{
+ U_CHAR *start = arg->expanded;
+ int length = arg->expand_length;
register U_CHAR *ibp;
register U_CHAR *obp;
- register U_CHAR *limit;
+ register const U_CHAR *limit;
register int c;
ibp = start;
}
}
- return obp - start;
+ arg->expand_length = obp - arg->expanded;
+
+ if (start != arg->expanded)
+ free (start);
}
\f
-/* my_strerror - return the descriptive text associated with an
- `errno' code. */
+/* notice - output message to stderr */
-static char *
-my_strerror (errnum)
- int errnum;
+static void
+notice VPARAMS ((const char * msgid, ...))
{
- char *result;
-
-#ifndef VMS
-#ifndef HAVE_STRERROR
- result = (char *) ((errnum < sys_nerr) ? sys_errlist[errnum] : 0);
-#else
- result = strerror (errnum);
-#endif
-#else /* VMS */
- /* VAXCRTL's strerror() takes an optional second argument, which only
- matters when the first argument is EVMSERR. However, it's simplest
- just to pass it unconditionally. `vaxc$errno' is declared in
- <errno.h>, and maintained by the library in parallel with `errno'.
- We assume that caller's `errnum' either matches the last setting of
- `errno' by the library or else does not have the value `EVMSERR'. */
-
- result = strerror (errnum, vaxc$errno);
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
+ va_list args;
- if (!result)
- result = "undocumented I/O error";
+ VA_START (args, msgid);
- return result;
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
+#endif
+
+ vnotice (msgid, args);
+ va_end (args);
+}
+
+static void
+vnotice (msgid, args)
+ const char *msgid;
+ va_list args;
+{
+ vfprintf (stderr, _(msgid), args);
}
/* error - print error message and increment count of errors. */
void
-error VPROTO ((char * msg, ...))
+error VPARAMS ((const char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
- msg = va_arg (args, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
#endif
-
- verror (msg, args);
+
+ verror (msgid, args);
va_end (args);
}
-static void
-verror (msg, args)
- char *msg;
+void
+verror (msgid, args)
+ const char *msgid;
va_list args;
{
int i;
}
if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
+ fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
+ ip->nominal_fname_len, stderr);
fprintf (stderr, ":%d: ", ip->lineno);
}
- vfprintf (stderr, msg, args);
+ vnotice (msgid, args);
fprintf (stderr, "\n");
errors++;
}
static void
error_from_errno (name)
- char *name;
+ const char *name;
{
int e = errno;
int i;
}
if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
+ fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
+ ip->nominal_fname_len, stderr);
fprintf (stderr, ":%d: ", ip->lineno);
}
- fprintf (stderr, "%s: %s\n", name, my_strerror (e));
+ fprintf (stderr, "%s: %s\n", name, xstrerror (e));
errors++;
}
/* Print error message but don't count it. */
void
-warning VPROTO ((char * msg, ...))
+warning VPARAMS ((const char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
- msg = va_arg (args, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
#endif
- vwarning (msg, args);
+ vwarning (msgid, args);
va_end (args);
}
static void
-vwarning (msg, args)
- char *msg;
+vwarning (msgid, args)
+ const char *msgid;
va_list args;
{
int i;
}
if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
+ fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
+ ip->nominal_fname_len, stderr);
fprintf (stderr, ":%d: ", ip->lineno);
}
- fprintf (stderr, "warning: ");
- vfprintf (stderr, msg, args);
+ notice ("warning: ");
+ vnotice (msgid, args);
fprintf (stderr, "\n");
}
static void
-error_with_line VPROTO ((int line, char * msg, ...))
+error_with_line VPARAMS ((int line, const char * msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
int line;
- char * msg;
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
line = va_arg (args, int);
- msg = va_arg (args, char *);
+ msgid = va_arg (args, const char *);
#endif
- verror_with_line (line, msg, args);
+ verror_with_line (line, msgid, args);
va_end (args);
}
+
static void
-verror_with_line (line, msg, args)
+verror_with_line (line, msgid, args)
int line;
- char *msg;
+ const char *msgid;
va_list args;
{
int i;
}
if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
+ fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
+ ip->nominal_fname_len, stderr);
fprintf (stderr, ":%d: ", line);
}
- vfprintf (stderr, msg, args);
+ vnotice (msgid, args);
fprintf (stderr, "\n");
errors++;
}
static void
-warning_with_line VPROTO ((int line, char * msg, ...))
+warning_with_line VPARAMS ((int line, const char * msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
int line;
- char * msg;
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
line = va_arg (args, int);
- msg = va_arg (args, char *);
+ msgid = va_arg (args, const char *);
#endif
- vwarning_with_line (line, msg, args);
+ vwarning_with_line (line, msgid, args);
va_end (args);
}
static void
-vwarning_with_line (line, msg, args)
+vwarning_with_line (line, msgid, args)
int line;
- char *msg;
+ const char *msgid;
va_list args;
{
int i;
}
if (ip != NULL) {
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
- fprintf (stderr, line ? ":%d: " : ": ", line);
+ fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
+ ip->nominal_fname_len, stderr);
+ if (line)
+ fprintf (stderr, ":%d: ", line);
+ else
+ fputs (": ", stderr);
}
- fprintf (stderr, "warning: ");
- vfprintf (stderr, msg, args);
+ notice ("warning: ");
+ vnotice (msgid, args);
fprintf (stderr, "\n");
}
/* Print an error message and maybe count it. */
void
-pedwarn VPROTO ((char * msg, ...))
+pedwarn VPARAMS ((const char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
#endif
-
+
if (pedantic_errors)
- verror (msg, args);
+ verror (msgid, args);
else
- vwarning (msg, args);
+ vwarning (msgid, args);
va_end (args);
}
void
-pedwarn_with_line VPROTO ((int line, char * msg, ...))
+pedwarn_with_line VPARAMS ((int line, const char * msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
int line;
- char * msg;
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
line = va_arg (args, int);
- msg = va_arg (args, char *);
+ msgid = va_arg (args, const char *);
#endif
-
+
if (pedantic_errors)
- verror_with_line (line, msg, args);
+ verror_with_line (line, msgid, args);
else
- vwarning_with_line (line, msg, args);
+ vwarning_with_line (line, msgid, args);
va_end (args);
}
giving specified file name and line number, not current. */
static void
-pedwarn_with_file_and_line VPROTO ((char *file, size_t file_len, int line,
- char * msg, ...))
+pedwarn_with_file_and_line VPARAMS ((const char *file, size_t file_len,
+ int line, const char * msgid, ...))
{
-#ifndef __STDC__
- char *file;
+#ifndef ANSI_PROTOTYPES
+ const char *file;
size_t file_len;
int line;
- char * msg;
+ const char * msgid;
#endif
va_list args;
if (!pedantic_errors && inhibit_warnings)
return;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
- file = va_arg (args, char *);
+#ifndef ANSI_PROTOTYPES
+ file = va_arg (args, const char *);
file_len = va_arg (args, size_t);
line = va_arg (args, int);
- msg = va_arg (args, char *);
+ msgid = va_arg (args, const char *);
#endif
if (file) {
- eprint_string (file, file_len);
+ fwrite (file, sizeof file[0], file_len, stderr);
fprintf (stderr, ":%d: ", line);
}
if (pedantic_errors)
errors++;
if (!pedantic_errors)
- fprintf (stderr, "warning: ");
-
- vfprintf (stderr, msg, args);
+ notice ("warning: ");
+ vnotice (msgid, args);
va_end (args);
fprintf (stderr, "\n");
}
+
+static void
+pedwarn_strange_white_space (ch)
+ int ch;
+{
+ switch (ch)
+ {
+ case '\f': pedwarn ("formfeed in preprocessing directive"); break;
+ case '\r': pedwarn ("carriage return in preprocessing directive"); break;
+ case '\v': pedwarn ("vertical tab in preprocessing directive"); break;
+ default: abort ();
+ }
+}
\f
/* Print the file names and line numbers of the #include
directives which led to the current file. */
ip = &instack[i];
if (first) {
first = 0;
- fprintf (stderr, "In file included");
+ notice ( "In file included from ");
} else {
- fprintf (stderr, ",\n ");
+ notice (",\n from ");
}
- fprintf (stderr, " from ");
- eprint_string (ip->nominal_fname, ip->nominal_fname_len);
+ fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
+ ip->nominal_fname_len, stderr);
fprintf (stderr, ":%d", ip->lineno);
}
if (! first)
if (minsize > obuf->length)
obuf->length = minsize;
- if ((p = (U_CHAR *) xrealloc (obuf->buf, obuf->length)) == NULL)
- memory_full ();
+ p = (U_CHAR *) xrealloc (obuf->buf, obuf->length);
obuf->bufp = p + (obuf->bufp - obuf->buf);
obuf->buf = p;
static HASHNODE *
install (name, len, type, value, hash)
- U_CHAR *name;
+ const U_CHAR *name;
int len;
enum node_type type;
- char *value;
+ const char *value;
int hash;
{
register HASHNODE *hp;
register int i, bucket;
- register U_CHAR *p, *q;
+ register U_CHAR *p;
+ register const U_CHAR *q;
if (len < 0) {
- p = name;
- while (is_idchar[*p])
- p++;
- len = p - name;
+ q = name;
+ while (is_idchar[*q])
+ q++;
+ len = q - name;
}
if (hash < 0)
HASHNODE *
lookup (name, len, hash)
- U_CHAR *name;
+ const U_CHAR *name;
int len;
int hash;
{
- register U_CHAR *bp;
+ register const U_CHAR *bp;
register HASHNODE *bucket;
if (len < 0) {
static int
hashf (name, len, hashsize)
- register U_CHAR *name;
+ register const U_CHAR *name;
register int len;
int hashsize;
{
static void
dump_defn_1 (base, start, length, of)
- U_CHAR *base;
+ const U_CHAR *base;
int start;
int length;
FILE *of;
{
- U_CHAR *p = base + start;
- U_CHAR *limit = base + start + length;
+ const U_CHAR *p = base + start;
+ const U_CHAR *limit = base + start + length;
if (traditional)
fwrite (p, sizeof (*p), length, of);
else {
while (p < limit) {
if (*p == '\"' || *p =='\'') {
- U_CHAR *p1 = skip_quoted_string (p, limit, 0, NULL_PTR,
- NULL_PTR, NULL_PTR);
+ const U_CHAR *p1 = skip_quoted_string (p, limit, 0, NULL_PTR,
+ NULL_PTR, NULL_PTR);
fwrite (p, sizeof (*p), p1 - p, of);
p = p1;
} else {
* refer to them.
*/
for (i = 'a'; i <= 'z'; i++) {
- is_idchar[i - 'a' + 'A'] = 1;
- is_idchar[i] = 1;
- is_idstart[i - 'a' + 'A'] = 1;
- is_idstart[i] = 1;
+ /* SKIP EBCIDIC holes, char must be a valid low case char */
+ if (ISLOWER(i)) {
+ is_idchar[TOUPPER(i)] = 1;
+ is_idchar[i] = 1;
+ is_idstart[TOUPPER(i)] = 1;
+ is_idstart[i] = 1;
+ }
}
for (i = '0'; i <= '9'; i++)
is_idchar[i] = 1;
is_space['\f'] = 1;
is_space['\n'] = 1;
is_space['\r'] = 1;
-
- char_name['\v'] = "vertical tab";
- char_name['\f'] = "formfeed";
- char_name['\r'] = "carriage return";
}
/* Initialize the built-in macros. */
FILE_BUF *inp;
FILE_BUF *outp;
{
- install ((U_CHAR *) "__LINE__", -1, T_SPECLINE, NULL_PTR, -1);
- install ((U_CHAR *) "__DATE__", -1, T_DATE, NULL_PTR, -1);
- install ((U_CHAR *) "__FILE__", -1, T_FILE, NULL_PTR, -1);
- install ((U_CHAR *) "__BASE_FILE__", -1, T_BASE_FILE, NULL_PTR, -1);
- install ((U_CHAR *) "__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, NULL_PTR, -1);
- install ((U_CHAR *) "__VERSION__", -1, T_VERSION, NULL_PTR, -1);
+ install ((const U_CHAR *) "__LINE__", -1, T_SPECLINE, NULL_PTR, -1);
+ install ((const U_CHAR *) "__DATE__", -1, T_DATE, NULL_PTR, -1);
+ install ((const U_CHAR *) "__FILE__", -1, T_FILE, NULL_PTR, -1);
+ install ((const U_CHAR *) "__BASE_FILE__", -1, T_BASE_FILE, NULL_PTR, -1);
+ install ((const U_CHAR *) "__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, NULL_PTR, -1);
+ install ((const U_CHAR *) "__VERSION__", -1, T_VERSION, NULL_PTR, -1);
#ifndef NO_BUILTIN_SIZE_TYPE
- install ((U_CHAR *) "__SIZE_TYPE__", -1, T_SIZE_TYPE, NULL_PTR, -1);
+ install ((const U_CHAR *) "__SIZE_TYPE__", -1, T_SIZE_TYPE, NULL_PTR, -1);
#endif
#ifndef NO_BUILTIN_PTRDIFF_TYPE
- install ((U_CHAR *) "__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, NULL_PTR, -1);
+ install ((const U_CHAR *) "__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, NULL_PTR, -1);
#endif
- install ((U_CHAR *) "__WCHAR_TYPE__", -1, T_WCHAR_TYPE, NULL_PTR, -1);
- install ((U_CHAR *) "__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE,
+#ifndef NO_BUILTIN_WCHAR_TYPE
+ install ((const U_CHAR *) "__WCHAR_TYPE__", -1, T_WCHAR_TYPE, NULL_PTR, -1);
+#endif
+ install ((const U_CHAR *) "__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE,
NULL_PTR, -1);
- install ((U_CHAR *) "__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE,
+ install ((const U_CHAR *) "__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE,
NULL_PTR, -1);
- install ((U_CHAR *) "__IMMEDIATE_PREFIX__", -1, T_IMMEDIATE_PREFIX_TYPE,
+ install ((const U_CHAR *) "__IMMEDIATE_PREFIX__", -1, T_IMMEDIATE_PREFIX_TYPE,
NULL_PTR, -1);
- install ((U_CHAR *) "__TIME__", -1, T_TIME, NULL_PTR, -1);
+ install ((const U_CHAR *) "__TIME__", -1, T_TIME, NULL_PTR, -1);
if (!traditional) {
- install ((U_CHAR *) "__STDC__", -1, T_CONST, "1", -1);
- install ((U_CHAR *) "__STDC_VERSION__", -1, T_CONST, "199409L", -1);
+ install ((const U_CHAR *) "__STDC__", -1, T_CONST, "1", -1);
+ install ((const U_CHAR *) "__STDC_VERSION__", -1, T_CONST, "199409L", -1);
}
- if (objc)
- install ((U_CHAR *) "__OBJC__", -1, T_CONST, "1", -1);
/* This is supplied using a -D by the compiler driver
so that it is present only when truly compiling with GNU C. */
/* install ((U_CHAR *) "__GNUC__", -1, T_CONST, "2", -1); */
- install ((U_CHAR *) "__HAVE_BUILTIN_SETJMP__", -1, T_CONST, "1", -1);
+ install ((const U_CHAR *) "__HAVE_BUILTIN_SETJMP__", -1, T_CONST, "1", -1);
if (debug_output)
{
outp, dp);
#endif
+#ifndef NO_BUILTIN_WCHAR_TYPE
sprintf (directive, " __WCHAR_TYPE__ %s\n", wchar_type);
output_line_directive (inp, outp, 0, same_file);
pass_thru_directive (udirective, &udirective[strlen (directive)],
outp, dp);
+#endif
sprintf (directive, " __DATE__ \"%s %2d %4d\"\n",
monthnames[timebuf->tm_mon],
while (*p) {
if (*p == '\"' || *p == '\'') {
int unterminated = 0;
- U_CHAR *p1 = skip_quoted_string (p, p + strlen ((char *) p), 0,
+ const U_CHAR *p1 = skip_quoted_string (p, p + strlen ((char *) p), 0,
NULL_PTR, NULL_PTR, &unterminated);
if (unterminated)
return;
- while (p != p1)
- *q++ = *p++;
+ while (p != p1) {
+ if (*p == '\\' && p[1] == '\n')
+ p += 2;
+ else if (*p == '\n')
+ {
+ *q++ = '\\';
+ *q++ = 'n';
+ p++;
+ }
+ else
+ *q++ = *p++;
+ }
} else if (*p == '\\' && p[1] == '\n')
p += 2;
/* Change newline chars into newline-markers. */
static void
make_assertion (option, str)
- char *option;
- char *str;
+ const char *option;
+ const char *str;
{
FILE_BUF *ip;
struct directive *kt;
--indepth;
}
\f
-#ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
-#endif
-
/* The previous include prefix, if any, is PREV_FILE_NAME.
Translate any pathnames with COMPONENT.
Allocate a new include prefix whose name is the
static struct file_name_list *
new_include_prefix (prev_file_name, component, prefix, name)
struct file_name_list *prev_file_name;
- char *component;
- char *prefix;
- char *name;
+ const char *component;
+ const char *prefix;
+ const char *name;
{
if (name == 0)
fatal ("Directory name missing after command line option");
static int
quote_string_for_make (dst, src)
char *dst;
- char *src;
+ const char *src;
{
- char *p = src;
+ const char *p = src;
int i = 0;
for (;;)
{
preceded by 2N backslashes represents N backslashes at
the end of a file name; and backslashes in other
contexts should not be doubled. */
- char *q;
+ const char *q;
for (q = p - 1; src < q && q[-1] == '\\'; q--)
{
if (dst)
static void
deps_output (string, spacer)
- char *string;
+ const char *string;
int spacer;
{
int size = quote_string_for_make ((char *) 0, string);
deps_buffer[deps_size] = 0;
}
\f
-static void
-fatal VPROTO ((char * msg, ...))
+void
+fatal VPARAMS ((const char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
va_list args;
fprintf (stderr, "%s: ", progname);
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
#endif
-
- vfprintf (stderr, msg, args);
+ vnotice (msgid, args);
va_end (args);
fprintf (stderr, "\n");
exit (FATAL_EXIT_CODE);
static void
perror_with_name (name)
- char *name;
+ const char *name;
{
- fprintf (stderr, "%s: %s: %s\n", progname, name, my_strerror (errno));
+ fprintf (stderr, "%s: %s: %s\n", progname, name, xstrerror (errno));
errors++;
}
static void
pfatal_with_name (name)
- char *name;
+ const char *name;
{
perror_with_name (name);
#ifdef VMS
{
fatal ("Memory exhausted.");
}
-
-
-GENERIC_PTR
-xmalloc (size)
- size_t size;
-{
- register GENERIC_PTR ptr = (GENERIC_PTR) malloc (size);
- if (!ptr)
- memory_full ();
- return ptr;
-}
-
-static GENERIC_PTR
-xrealloc (old, size)
- GENERIC_PTR old;
- size_t size;
-{
- register GENERIC_PTR ptr = (GENERIC_PTR) realloc (old, size);
- if (!ptr)
- memory_full ();
- return ptr;
-}
-
-static GENERIC_PTR
-xcalloc (number, size)
- size_t number, size;
-{
- register size_t total = number * size;
- register GENERIC_PTR ptr = (GENERIC_PTR) malloc (total);
- if (!ptr)
- memory_full ();
- bzero (ptr, total);
- return ptr;
-}
-
-static char *
-savestring (input)
- char *input;
-{
- size_t size = strlen (input);
- char *output = xmalloc (size + 1);
- strcpy (output, input);
- return output;
-}
\f
#ifdef VMS
return result;
}
+
+static size_t
+VMS_fwrite (ptr, size, nitems, stream)
+ void const *ptr;
+ size_t size;
+ size_t nitems;
+ FILE *stream;
+{
+ /* VMS fwrite has undesirable results
+ if STREAM happens to be a record oriented file.
+ Work around this problem by writing each character individually. */
+ char const *p = ptr;
+ size_t bytes = size * nitems;
+ char *lim = p + bytes;
+
+ while (p < lim)
+ if (putc (*p++, stream) == EOF)
+ return 0;
+
+ return bytes;
+}
#endif /* VMS */