/* C Compatible Compiler Preprocessor (CCCP)
- Copyright (C) 1986, 87, 89, 92-95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1986, 87, 89, 92-96, 1997 Free Software Foundation, Inc.
Written by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
#define STANDARD_INCLUDE_DIR "/usr/include"
#endif
-#ifndef LOCAL_INCLUDE_DIR
-#define LOCAL_INCLUDE_DIR "/usr/local/include"
-#endif
-
#include "pcp.h"
/* By default, colon separates directories in a path. */
# endif /* !defined (BSTRING) && (defined (USG) || defined (VMS)) */
#endif /* ! STDC_HEADERS */
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __attribute__(x)
#endif
# define VA_START(va_list, var) va_start (va_list, var)
# define PRINTF_ALIST(msg) char *msg, ...
# define PRINTF_DCL(msg)
-# define PRINTF_PROTO(ARGS, m, n) PROTO (ARGS) __attribute__ ((format (printf, m, n)))
+# define PRINTF_PROTO(ARGS, m, n) PROTO (ARGS) __attribute__ ((format (__printf__, m, n)))
#else
# include <varargs.h>
# define VA_START(va_list, var) va_start (va_list)
# define PRINTF_ALIST(msg) msg, va_alist
# define PRINTF_DCL(msg) char *msg; va_dcl
-# define PRINTF_PROTO(ARGS, m, n) () __attribute__ ((format (printf, m, n)))
+# define PRINTF_PROTO(ARGS, m, n) () __attribute__ ((format (__printf__, m, n)))
# define vfprintf(file, msg, args) \
{ \
char *a0 = va_arg(args, char *); \
/* VMS-specific definitions */
#ifdef VMS
#include <descrip.h>
-#define O_RDONLY 0 /* Open arg for Read/Only */
-#define O_WRONLY 1 /* Open arg for Write/Only */
#define read(fd,buf,size) VMS_read (fd,buf,size)
#define write(fd,buf,size) VMS_write (fd,buf,size)
#define open(fname,mode,prot) VMS_open (fname,mode,prot)
#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 */
-#ifdef __GNUC__
-#define BSTRING /* VMS/GCC supplies the bstring routines */
-#endif /* __GNUC__ */
#endif /* VMS */
#ifndef O_RDONLY
int traditional;
+/* Nonzero for the 1989 C Standard, including corrigenda and amendments. */
+
+int c89;
+
/* Nonzero causes output not to be done,
but directives such as #define that have side effects
are still obeyed. */
/* For cross-compilation, this dir name is generated
automatically in Makefile.in. */
{ CROSS_INCLUDE_DIR, 0, 0 },
+#ifdef TOOL_INCLUDE_DIR
/* This is another place that the target system's headers might be. */
{ TOOL_INCLUDE_DIR, 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, 1 },
+#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, 0, 0 },
+#endif
/* This is the dir for fixincludes. Put it just before
the files that we fix. */
{ GCC_INCLUDE_DIR, 0, 0 },
/* table to tell if char can be first char of a c identifier. */
U_CHAR is_idstart[256];
/* table to tell if c is horizontal space. */
-U_CHAR is_hor_space[256];
+static U_CHAR is_hor_space[256];
/* table to tell if c is horizontal or vertical space. */
-static U_CHAR is_space[256];
+U_CHAR is_space[256];
/* names of some characters */
static char *char_name[256];
case 'l':
if (! strcmp (argv[i], "-lang-c"))
- cplusplus = 0, cplusplus_comments = 1, objc = 0;
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 0;
if (! strcmp (argv[i], "-lang-c89"))
- cplusplus = 0, cplusplus_comments = 0, objc = 0;
+ cplusplus = 0, cplusplus_comments = 0, c89 = 1, objc = 0;
if (! strcmp (argv[i], "-lang-c++"))
- cplusplus = 1, cplusplus_comments = 1, objc = 0;
+ cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 0;
if (! strcmp (argv[i], "-lang-objc"))
- objc = 1, cplusplus = 0, cplusplus_comments = 1;
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 1;
if (! strcmp (argv[i], "-lang-objc++"))
- objc = 1, cplusplus = 1, cplusplus_comments = 1;
+ cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 1;
if (! strcmp (argv[i], "-lang-asm"))
lang_asm = 1;
if (! strcmp (argv[i], "-lint"))
/* A single quoted string is treated like a double -- some
programs (e.g., troff) are perverse this way */
- if (ident_length)
+ /* Handle any pending identifier;
+ but the L in L'...' or L"..." is not an identifier. */
+ if (ident_length
+ && ! (ident_length == 1 && hash == HASHSTEP (0, 'L')))
goto specialchar;
start_line = ip->lineno;
}
*obp++ = c;
/* A sign can be part of a preprocessing number
- if it follows an e. */
- if (c == 'e' || c == 'E') {
+ if it follows an `e' or `p'. */
+ if (c == 'e' || c == 'E' || c == 'p' || c == 'P') {
while (ibp[0] == '\\' && ibp[1] == '\n') {
++ip->lineno;
ibp += 2;
}
if (*ibp == '+' || *ibp == '-') {
*obp++ = *ibp++;
- /* But traditional C does not let the token go past the sign. */
- if (traditional)
+ /* But traditional C does not let the token go past the sign,
+ and C89 does not allow `p'. */
+ if (traditional || (c89 && (c == 'p' || c == 'P')))
break;
}
}
if (!traditional && obp != op->buf) {
switch (obp[-1]) {
case '!': case '%': case '&': case '*':
- case '+': case '-': case '/': case ':':
- case '<': case '=': case '>': case '^':
- case '|':
+ case '+': case '-': case '.': case '/':
+ case ':': case '<': case '=': case '>':
+ case '^': case '|':
/* If we are expanding a macro arg, make a newline marker
to separate the tokens. If we are making real output,
a plain space will do. */
if (!is_idstart[*ip->bufp])
goto oops;
+ if (ip->bufp[0] == 'L' && (ip->bufp[1] == '\'' || ip->bufp[1] == '"'))
+ goto oops;
if ((hp = lookup (ip->bufp, -1, -1))) {
if (pcp_outfile && pcp_inside_if
&& (hp->type == T_CONST
int retried = 0; /* Have already tried macro
expanding the include line*/
int angle_brackets = 0; /* 0 for "...", 1 for <...> */
+#ifdef VMS
+ int vaxc_include = 0; /* 1 for token without punctuation */
+#endif
int pcf = -1;
char *pcfbuf;
char *pcfbuflimit;
while (fin != limit && (!isspace(*fin)))
*fend++ = *fin++;
warning ("VAX-C-style include specification found, use '#include <filename.h>' !");
+ vaxc_include = 1;
if (fin == limit) {
angle_brackets = 1;
/* If -I-, start with the first -I dir after the -I-. */
full VMS file specification */
if (searchptr->fname[0]) {
/* Fix up the filename */
- hack_vms_include_specification (fname);
+ hack_vms_include_specification (fname, vaxc_include);
} else {
- /* This is a normal VMS filespec, so use it unchanged. */
+ /* This is a normal VMS filespec, so use it unchanged. */
strcpy (fname, fbeg);
/* if it's '#include filename', add the missing .h */
- if (index(fname,'.')==NULL) {
+ if (vaxc_include && index(fname,'.')==NULL) {
strcat (fname, ".h");
}
}
for (p = symname; is_idchar[*p]; p++)
;
sym_length = p - symname;
- if (sym_length == 0)
+ if (sym_length == 0
+ || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
error ("invalid %s name", usage);
else if (!is_idstart[*symname]
|| (sym_length == 7 && ! bcmp (symname, "defined", 7)))
p++;
SKIP_WHITE_SPACE (p);
}
- if (! is_idstart[*p] || nargs == 0)
+ if (! is_idstart[*p] || nargs == 0
+ || (*p == 'L' && (p[1] == '\'' || p[1] == '"')))
error ("`#' operator is not followed by a macro argument name");
else
stringify = p;
while (p != limit && is_idchar[*p]) p++;
id_len = p - id_beg;
- if (is_idstart[c]) {
+ if (is_idstart[c]
+ && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {
register struct arglist *arg;
for (arg = arglist; arg != NULL; arg = arg->next) {
struct directive *keyword;
{
int length = limit - buf;
- U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
+ U_CHAR *copy = (U_CHAR *) alloca (length + 1);
bcopy ((char *) buf, (char *) copy, length);
copy[length] = 0;
SKIP_WHITE_SPACE (copy);
struct directive *keyword;
{
int length = limit - buf;
- U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
+ U_CHAR *copy = (U_CHAR *) alloca (length + 1);
bcopy ((char *) buf, (char *) copy, length);
copy[length] = 0;
SKIP_WHITE_SPACE (copy);
}
}
- /* Don't output a line number of 0 if we can help it. */
- if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length
- && *ip->bufp == '\n') {
+ /* Output a positive line number if possible. */
+ while (ip->lineno <= 0 && ip->bufp - ip->buf < ip->length
+ && *ip->bufp == '\n') {
ip->lineno++;
ip->bufp++;
}
VMS file specification. */
static void
-hack_vms_include_specification (fname)
+hack_vms_include_specification (fname, vaxc_include)
char *fname;
+ int vaxc_include;
{
register char *cp, *cp1, *cp2;
int f, check_filename_before_returning;
* Check if we have a vax-c style '#include filename'
* and add the missing .h
*/
- if (!index (cp,'.'))
+ if (vaxc_include && !index (cp,'.'))
strcat (cp, ".h");
cp2 = Local; /* initialize */