OSDN Git Service

update doc for CONST_{,DOUBLE_}OK_FOR_LETTER_P, EXTRA_CONTSTRAINT
[pf3gnuchains/gcc-fork.git] / gcc / cccp.c
index 93f5c35..8df72f2 100644 (file)
@@ -219,17 +219,11 @@ my_bzero (b, length)
 /* 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 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)
 static int VMS_fstat (), VMS_stat ();
-static int VMS_read ();
-static int VMS_write ();
 static int VMS_open ();
 static FILE * VMS_fopen ();
 static FILE * VMS_freopen ();
@@ -237,11 +231,13 @@ 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 */
-#ifdef __GNUC__
-#define BSTRING                        /* VMS/GCC supplies the bstring routines */
-#endif /* __GNUC__ */
 #endif /* VMS */
 
+/* Windows does not natively support inodes, and neither does MSDOS.  */
+#if (defined (_WIN32) && ! defined (CYGWIN32)) || defined (__MSDOS__)
+#define INO_T_EQ(a, b) 0
+#endif
+
 #ifndef O_RDONLY
 #define O_RDONLY 0
 #endif
@@ -310,11 +306,7 @@ extern char *version_string;
 #ifndef VMS
 #ifndef HAVE_STRERROR
 extern int sys_nerr;
-#if defined(bsd4_4)
-extern const char *const sys_errlist[];
-#else
 extern char *sys_errlist[];
-#endif
 #else  /* HAVE_STRERROR */
 char *strerror ();
 #endif
@@ -457,6 +449,10 @@ static int warn_stringify;
 
 static int warn_trigraphs;
 
+/* Nonzero means warn if undefined identifiers are evaluated in an #if.  */
+
+int warn_undef;
+
 /* Nonzero means warn if #import is used.  */
 
 static int warn_import = 1;
@@ -469,6 +465,10 @@ static int warnings_are_errors;
 
 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.  */
@@ -1020,9 +1020,9 @@ U_CHAR is_idchar[256];
 /* 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];
 
@@ -1213,7 +1213,8 @@ static GENERIC_PTR xcalloc PROTO((size_t, size_t));
 static char *savestring PROTO((char *));
 \f
 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
-   retrying if necessary.  Return a negative value if an error occurs,
+   retrying if necessary.  If MAX_READ_LEN is defined, read at most
+   that bytes at a time.  Return a negative value if an error occurs,
    otherwise return the actual number of bytes read,
    which must be LEN unless end-of-file was reached.  */
 
@@ -1223,9 +1224,16 @@ safe_read (desc, ptr, len)
      char *ptr;
      int len;
 {
-  int left = len;
+  int left, rcount, nchars;
+
+  left = len;
   while (left > 0) {
-    int nchars = read (desc, ptr, left);
+    rcount = left;
+#ifdef MAX_READ_LEN
+    if (rcount > MAX_READ_LEN)
+      rcount = MAX_READ_LEN;
+#endif
+    nchars = read (desc, ptr, rcount);
     if (nchars < 0)
       {
 #ifdef EINTR
@@ -1243,7 +1251,8 @@ safe_read (desc, ptr, len)
 }
 
 /* Write LEN bytes at PTR to descriptor DESC,
-   retrying if necessary, and treating any real error as fatal.  */
+   retrying if necessary, and treating any real error as fatal.
+   If MAX_WRITE_LEN is defined, write at most that many bytes at a time.  */
 
 static void
 safe_write (desc, ptr, len)
@@ -1251,8 +1260,15 @@ safe_write (desc, ptr, len)
      char *ptr;
      int len;
 {
+  int wcount, written;
+
   while (len > 0) {
-    int written = write (desc, ptr, len);
+    wcount = len;
+#ifdef MAX_WRITE_LEN
+    if (wcount > MAX_WRITE_LEN)
+      wcount = MAX_WRITE_LEN;
+#endif
+    written = write (desc, ptr, wcount);
     if (written < 0)
       {
 #ifdef EINTR
@@ -1486,10 +1502,10 @@ main (argc, argv)
          if (i + 1 == argc)
            fatal ("Filename missing after -pcp option");
          pcp_fname = argv[++i];
-         pcp_outfile = 
-           ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
-            ? fopen (pcp_fname, "w")
-            : stdout);
+         pcp_outfile
+           ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
+              ? fopen (pcp_fname, "w")
+              : stdout);
          if (pcp_outfile == 0)
            pfatal_with_name (pcp_fname);
          no_precomp = 1;
@@ -1507,15 +1523,15 @@ main (argc, argv)
 
       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"))
@@ -1547,6 +1563,10 @@ main (argc, argv)
          warn_stringify = 1;
        else if (!strcmp (argv[i], "-Wno-traditional"))
          warn_stringify = 0;
+       else if (!strcmp (argv[i], "-Wundef"))
+         warn_undef = 1;
+       else if (!strcmp (argv[i], "-Wno-undef"))
+         warn_undef = 0;
        else if (!strcmp (argv[i], "-Wimport"))
          warn_import = 1;
        else if (!strcmp (argv[i], "-Wno-import"))
@@ -2813,7 +2833,10 @@ do { ip = &instack[indepth];             \
       /* 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;
@@ -3063,16 +3086,17 @@ do { ip = &instack[indepth];            \
          }
          *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;
            }
          }
@@ -3414,9 +3438,9 @@ randomchar:
              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.  */
@@ -3525,9 +3549,14 @@ expand_to_temp_buffer (buf, limit, output_marks, assertions)
 
   obuf.length = length * 2 + 100; /* Usually enough.  Why be stingy?  */
   obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
+  obuf.nominal_fname = 0;
+  obuf.inc = 0;
+  obuf.dir = 0;
   obuf.fname = 0;
   obuf.macro = 0;
+  obuf.if_stack = 0;
   obuf.free_ptr = 0;
+  obuf.system_header_p = 0;
 
   CHECK_DEPTH ({return obuf;});
 
@@ -4123,6 +4152,8 @@ special_symbol (hp, op)
 
     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
@@ -4199,11 +4230,22 @@ do_include (buf, limit, op, keyword)
   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;
   int pcfnum;
 
+  if (pedantic && !instack[indepth].system_header_p)
+    {
+      if (importing)
+       pedwarn ("ANSI C does not allow `#import'");
+      if (skip_dirs)
+       pedwarn ("ANSI C does not allow `#include_next'");
+    }
+
   if (importing && warn_import && !inhibit_warnings
       && !instack[indepth].system_header_p && !import_warning) {
     import_warning = 1;
@@ -4310,6 +4352,7 @@ get_filename:
       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-.  */
@@ -4427,12 +4470,12 @@ get_filename:
          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");
        }
       }
@@ -5521,8 +5564,8 @@ create_definition (buf, limit, op)
       while (is_idchar[*bp]) {
        bp++;
        /* do we have a "special" rest-args extension here? */
-       if (limit - bp > REST_EXTENSION_LENGTH &&
-           bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
+       if (limit - bp > REST_EXTENSION_LENGTH
+           && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
          rest_args = 1;
          temp->rest_args = 1;
          break;
@@ -5554,8 +5597,8 @@ create_definition (buf, limit, op)
        struct arglist *otemp;
 
        for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
-         if (temp->length == otemp->length &&
-             bcmp (temp->name, otemp->name, temp->length) == 0) {
+         if (temp->length == otemp->length
+             && bcmp (temp->name, otemp->name, temp->length) == 0) {
              error ("duplicate argument name `%.*s' in `#define'",
                     temp->length, temp->name);
              goto nope;
@@ -5716,7 +5759,8 @@ check_macro_name (symname, usage)
   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)))
@@ -5942,7 +5986,8 @@ collect_expansion (buf, end, nargs, arglist)
            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;
@@ -6005,7 +6050,8 @@ collect_expansion (buf, end, nargs, arglist)
       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) {
@@ -6629,8 +6675,7 @@ do_line (buf, limit, op, keyword)
       }
     }
 
-    hash_bucket =
-      &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
+    hash_bucket = &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
     for (hp = *hash_bucket; hp != NULL; hp = hp->next)
       if (hp->length == fname_length &&
          bcmp (hp->value.cpval, fname, fname_length) == 0) {
@@ -6709,7 +6754,7 @@ do_error (buf, limit, op, keyword)
      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);
@@ -6728,11 +6773,13 @@ do_warning (buf, limit, op, keyword)
      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);
-  warning ("#warning %s", copy);
+  /* 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;
 }
 
@@ -6917,8 +6964,8 @@ do_elif (buf, limit, op, keyword)
     if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
       error ("`#elif' after `#else'");
       fprintf (stderr, " (matches line %d", if_stack->lineno);
-      if (if_stack->fname != NULL && ip->fname != NULL &&
-         strcmp (if_stack->fname, ip->nominal_fname) != 0)
+      if (if_stack->fname != NULL && ip->fname != NULL
+         && strcmp (if_stack->fname, ip->nominal_fname) != 0)
        fprintf (stderr, ", file %s", if_stack->fname);
       fprintf (stderr, ")\n");
     }
@@ -7036,9 +7083,9 @@ do_xifdef (buf, limit, op, keyword)
 
     if (pcp_outfile) {
       /* Output a precondition for this macro.  */
-      if (hp &&
-         (hp->type == T_CONST
-          || (hp->type == T_MACRO && hp->value.defn->predefined)))
+      if (hp
+         && (hp->type == T_CONST
+             || (hp->type == T_MACRO && hp->value.defn->predefined)))
        fprintf (pcp_outfile, "#define %s\n", hp->name);
       else {
        U_CHAR *cp = buf;
@@ -7832,9 +7879,9 @@ output_line_directive (ip, op, conditional, file_change)
     }
   }
 
-  /* 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++;
   }
@@ -10001,8 +10048,9 @@ savestring (input)
    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;
@@ -10016,7 +10064,7 @@ hack_vms_include_specification (fname)
    * 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 */
@@ -10143,59 +10191,6 @@ hack_vms_include_specification (fname)
 \f
 #ifdef VMS
 
-/* These are the read/write replacement routines for
-   VAX-11 "C".  They make read/write behave enough
-   like their UNIX counterparts that CCCP will work */
-
-static int
-read (fd, buf, size)
-     int fd;
-     char *buf;
-     int size;
-{
-#undef read    /* Get back the REAL read routine */
-  register int i;
-  register int total = 0;
-
-  /* Read until the buffer is exhausted */
-  while (size > 0) {
-    /* Limit each read to 32KB */
-    i = (size > (32*1024)) ? (32*1024) : size;
-    i = read (fd, buf, i);
-    if (i <= 0) {
-      if (i == 0) return (total);
-      return (i);
-    }
-    /* Account for this read */
-    total += i;
-    buf += i;
-    size -= i;
-  }
-  return (total);
-}
-
-static int
-write (fd, buf, size)
-     int fd;
-     char *buf;
-     int size;
-{
-#undef write   /* Get back the REAL write routine */
-  int i;
-  int j;
-
-  /* Limit individual writes to 32Kb */
-  i = size;
-  while (i > 0) {
-    j = (i > (32*1024)) ? (32*1024) : i;
-    if (write (fd, buf, j) < 0) return (-1);
-    /* Account for the data written */
-    buf += j;
-    i -= j;
-  }
-  return (size);
-}
-
 /* The following wrapper functions supply additional arguments to the VMS
    I/O routines to optimize performance with file handling.  The arguments
    are: