/* Lexical analyzer for GNU CHILL. -*- C -*-
- Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GNU CC.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
\f
-#include <stdio.h>
-#include <errno.h>
-#include <setjmp.h>
-#include <ctype.h>
-#include <sys/types.h>
+#include "config.h"
+#include "system.h"
#include <sys/stat.h>
-#include "config.h"
#include "tree.h"
#include "input.h"
#include "flags.h"
#include "parse.h"
#include "obstack.h"
+#include "toplev.h"
+#include "tm_p.h"
#ifdef MULTIBYTE_CHARS
-#include <stdlib.h>
#include <locale.h>
#endif
/* include the keyword recognizers */
#include "hash.h"
-#undef strchr
-
FILE* finput;
+#if 0
static int last_token = 0;
/* Sun's C compiler warns about the safer sequence
do { .. } while 0
when there's a 'return' inside the braces, so don't use it */
#define RETURN_TOKEN(X) { last_token = X; return (X); }
+#endif
/* This is set non-zero to force incoming tokens to lowercase. */
extern int ignore_case;
extern struct obstack permanent_obstack;
extern struct obstack temporary_obstack;
-#ifndef errno
-extern int errno;
-#endif
-
-extern tree build_string_type PROTO((tree, tree));
-extern void error PROTO((char *, ...));
-extern void error_with_file_and_line PROTO((char *, int, char *, ...));
-extern void grant_use_seizefile PROTO((char *));
-extern void pedwarn PROTO((char *, ...));
-extern void pfatal_with_name PROTO((char *));
-extern void push_obstacks PROTO((struct obstack *, struct obstack *));
-extern void set_identifier_size PROTO((int));
-extern void sorry PROTO((char *, ...));
-extern int target_isinf PROTO((REAL_VALUE_TYPE));
-extern int tolower PROTO((int));
-extern void warning PROTO((char *, ...));
-
/* forward declarations */
-static void close_input_file PROTO((char *));
-static tree convert_bitstring PROTO((char *));
-static tree convert_integer PROTO((char *));
-static void maybe_downcase PROTO((char *));
-static int maybe_number PROTO((char *));
-static tree equal_number PROTO((void));
-static void handle_use_seizefile_directive PROTO((int));
-static int handle_name PROTO((tree));
-static void push_back PROTO((int));
-static char *readstring PROTO((int, int *));
-static void read_directive PROTO((void));
-static tree read_identifier PROTO((int));
-static tree read_number PROTO((int));
-static void skip_c_comment PROTO((void));
-static void skip_line_comment PROTO((void));
-static int skip_whitespace PROTO((void));
-static tree string_or_char PROTO((int, char *));
+static void close_input_file PARAMS ((const char *));
+static tree convert_bitstring PARAMS ((char *));
+static tree convert_integer PARAMS ((char *));
+static void maybe_downcase PARAMS ((char *));
+static int maybe_number PARAMS ((const char *));
+static tree equal_number PARAMS ((void));
+static void handle_use_seizefile_directive PARAMS ((int));
+static int handle_name PARAMS ((tree));
+static char *readstring PARAMS ((int, int *));
+static void read_directive PARAMS ((void));
+static tree read_identifier PARAMS ((int));
+static tree read_number PARAMS ((int));
+static void skip_c_comment PARAMS ((void));
+static void skip_line_comment PARAMS ((void));
+static int skip_whitespace PARAMS ((void));
+static tree string_or_char PARAMS ((int, const char *));
+static void ch_lex_init PARAMS ((void));
+static void skip_directive PARAMS ((void));
+static int same_file PARAMS ((const char *, const char *));
+static int getlc PARAMS ((FILE *));
/* next variables are public, because ch-actions uses them */
}
-char *
+const char *
init_parse (filename)
- char *filename;
+ const char *filename;
{
int lowercase_standard_names = ignore_case || ! special_UC;
}
else
finput = fopen (filename, "r");
+
if (finput == 0)
- pfatal_with_name (filename);
+ fatal_io_error ("can't open %s", filename);
#ifdef IO_BUFFER_SIZE
setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
fclose (finput);
}
\f
-static int yywrap ();
+static int yywrap PARAMS ((void));
+static int yy_refill PARAMS ((void));
#define YY_PUTBACK_SIZE 5
#define YY_BUF_SIZE 1000
static char *yy_cur = yy_buffer + YY_PUTBACK_SIZE;
static char *yy_lim = yy_buffer + YY_PUTBACK_SIZE;
-int yy_refill ()
+static int
+yy_refill ()
{
char *buf = yy_buffer + YY_PUTBACK_SIZE;
int c, result;
break;
if (ch == '_')
continue;
- if (!isxdigit (ch)) /* error on non-hex digit */
+ if (!ISXDIGIT (ch)) /* error on non-hex digit */
{
if (pass == 1)
error ("invalid C'xx' ");
for (;;)
{
ch = input ();
- if (isalnum (ch))
+ if (ISALNUM (ch))
obstack_1grow (&temporary_obstack, ch);
else if (ch != '_')
break;
case '.':
nextc = input ();
unput (nextc);
- if (isdigit (nextc)) /* || nextc == '_') we don't start numbers with '_' */
+ if (ISDIGIT (nextc)) /* || nextc == '_') we don't start numbers with '_' */
goto number;
return DOT;
case '0': case '1': case '2': case '3': case '4':
static void
close_input_file (fn)
- char *fn;
+ const char *fn;
{
if (finput == NULL)
abort ();
first = input ();
if (first == EOF)
break;
- if (! isalnum (first) && first != '_')
+ if (! ISALNUM (first) && first != '_')
{
unput (first);
break;
struct resword *tp;
tp = in_word_set (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
if (tp != NULL
- && special_UC == isupper (tp->name[0])
+ && special_UC == ISUPPER ((unsigned char) tp->name[0])
&& (tp->flags == RESERVED || tp->flags == PREDEF))
{
if (tp->rid != NORID)
if (ch != '_')
obstack_1grow (&temporary_obstack, ch);
ch = input ();
- if (! isdigit (ch) && ch != '_')
+ if (! ISDIGIT (ch) && ch != '_')
break;
}
if (ch == '.')
if (ch != '_')
obstack_1grow (&temporary_obstack, ch);
ch = input ();
- } while (isdigit (ch) || ch == '_');
+ } while (ISDIGIT (ch) || ch == '_');
is_float++;
}
if (ch == 'd' || ch == 'D' || ch == 'e' || ch == 'E')
obstack_1grow (&temporary_obstack, ch);
ch = input ();
}
- if (isdigit (ch) || ch == '_')
+ if (ISDIGIT (ch) || ch == '_')
{
do
{
if (ch != '_')
obstack_1grow (&temporary_obstack, ch);
ch = input ();
- } while (isdigit (ch) || ch == '_');
+ } while (ISDIGIT (ch) || ch == '_');
}
else
{
struct resword *tp;
tree id;
int ch = skip_whitespace();
- if (isalpha (ch) || ch == '_')
+ if (ISALPHA (ch) || ch == '_')
id = read_identifier (ch);
else if (ch == EOF)
{
return;
}
tp = in_word_set (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
- if (tp == NULL || special_UC != isupper (tp->name[0]))
+ if (tp == NULL || special_UC != ISUPPER ((unsigned char) tp->name[0]))
{
if (pass == 1)
warning ("unrecognized compiler directive `%s'",
tree
build_chill_string (len, str)
int len;
- char *str;
+ const char *str;
{
tree t;
static tree
string_or_char (len, str)
int len;
- char *str;
+ const char *str;
{
tree result;
return;
while (*str)
{
- if (isupper (*str))
- *str = tolower (*str);
+ *str = TOLOWER (*str);
str++;
}
}
static int
maybe_number (s)
- char *s;
+ const char *s;
{
char fc;
break;
case 'h':
case 'H':
- if (!isxdigit (*s))
+ if (!ISXDIGIT ((unsigned char) *s))
return 0;
break;
case 'b':
}
return 1;
}
-
-static void
-push_back (c)
-char c;
-{
- if (c == '\n')
- lineno--;
- unput (c);
-}
\f
static char *
readstring (terminator, len)
int c;
unsigned allocated = 1024;
char *tmp = xmalloc (allocated);
- int i = 0;
+ unsigned i = 0;
for (;;)
{
}
else if (base == 10)
{
- if (! isdigit (cc))
+ if (! ISDIGIT (cc))
cc = -1;
else
cc -= '0';
}
else if (base == 16)
{
- if (!isxdigit (cc))
+ if (!ISXDIGIT (cc))
cc = -1;
else
{
base = 2;
break;
default:
- if (!isdigit (*p)) /* this test is for equal_number () */
+ if (!ISDIGIT (*p)) /* this test is for equal_number () */
{
obstack_free (&temporary_obstack, intchars);
return 0;
/* Move p to stack so we can re-use temporary_obstack for result. */
char *oldp = (char*) alloca (strlen (p) + 1);
- if (oldp == 0) fatal ("stack space exhausted");
strcpy (oldp, p);
obstack_free (&temporary_obstack, p);
p = oldp;
static int
same_file (filename1, filename2)
- char *filename1;
- char *filename2;
+ const char *filename1;
+ const char *filename2;
{
struct stat s[2];
- char *fn_input[2];
+ const char *fn_input[2];
int i, stat_status;
- extern char *strchr();
if (grant_only_flag)
/* do nothing in this case */
for (i = 0; i < 2; i++)
{
stat_status = stat (fn_input[i], &s[i]);
- if (stat_status < 0 &&
- strchr (fn_input[i], '/') == 0)
+ if (stat_status < 0
+ && strchr (fn_input[i], '/') == 0)
{
STRING_LIST *plp;
- char *path;
+ char *path;
for (plp = seize_path_list; plp != 0; plp = plp->next)
{
- path = (char *)xmalloc (strlen (fn_input[i]) +
- strlen (plp->str) + 2);
+ path = (char *) xmalloc (strlen (fn_input[i])
+ + strlen (plp->str) + 2);
sprintf (path, "%s/%s", plp->str, fn_input[i]);
stat_status = stat (path, &s[i]);
free (path);
break;
}
}
+
if (stat_status < 0)
- pfatal_with_name (fn_input[i]);
+ fatal_io_error ("can't find %s", fn_input[i]);
}
return s[0].st_ino == s[1].st_ino && s[0].st_dev == s[1].st_dev;
}
/*
* get input, convert to lower case for comparison
*/
-int
+static int
getlc (file)
FILE *file;
{
register int c;
c = getc (file);
- if (isupper (c) && ignore_case)
- c = tolower (c);
+ if (ignore_case)
+ c = TOLOWER (c);
return c;
}
\f
}
#endif /* HANDLE_PRAGMA */
+#ifdef HANDLE_GENERIC_PRAGMAS
+/* Handle a generic #pragma directive.
+ BUFFER contains the text we read after `#pragma'. Processes the entire input
+ line and return non-zero iff the pragma was successfully processed. */
+
+static int
+handle_generic_pragma (buffer)
+ char * buffer;
+{
+ register int c;
+
+ for (;;)
+ {
+ char * buff;
+
+ handle_pragma_token (buffer, NULL);
+
+ c = getc (finput);
+
+ while (c == ' ' || c == '\t')
+ c = getc (finput);
+ ungetc (c, finput);
+
+ if (c == '\n' || c == EOF)
+ return handle_pragma_token (NULL, NULL);
+
+ /* Read the next word of the pragma into the buffer. */
+ buff = buffer;
+ do
+ {
+ * buff ++ = c;
+ c = getc (finput);
+ }
+ while (c != EOF && ! ISSPACE (c) && buff < buffer + 128);
+ /* XXX shared knowledge about size of buffer. */
+
+ ungetc (c, finput);
+
+ * -- buff = 0;
+ }
+}
+#endif /* HANDLE_GENERIC_PRAGMAS */
+\f
/* At the beginning of a line, increment the line number and process
any #-directive on this line. If the line is a #-directive, read
the entire line and return a newline. Otherwise, return the line's
it and ignore it; otherwise, ignore the line, with an error
if the word isn't `pragma', `ident', `define', or `undef'. */
- if (isupper (c) && ignore_case)
- c = tolower (c);
+ if (ignore_case)
+ c = TOLOWER (c);
if (c >= 'a' && c <= 'z')
{
&& getlc (finput) == 'g'
&& getlc (finput) == 'm'
&& getlc (finput) == 'a'
- && (isspace (c = getlc (finput))))
+ && (c = getlc (finput), ISSPACE (c)))
{
#ifdef HANDLE_PRAGMA
static char buffer [128];
char * buff = buffer;
/* Read the pragma name into a buffer. */
- while (isspace (c = getlc (finput)))
+ while (c = getlc (finput), ISSPACE (c))
continue;
do
* buff ++ = c;
c = getlc (finput);
}
- while (c != EOF && ! isspace (c) && c != '\n'
+ while (c != EOF && ! ISSPACE (c) && c != '\n'
&& buff < buffer + 128);
pragma_ungetc (c);
* -- buff = 0;
- (void) HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer);
+ if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
+ goto skipline;
#endif /* HANDLE_PRAGMA */
+
+#ifdef HANDLE_GENERIC_PRAGMAS
+ if (handle_generic_pragma (buffer))
+ goto skipline;
+#endif /* HANDLE_GENERIC_PRAGMAS */
+
goto skipline;
}
}
&& getlc (finput) == 'i'
&& getlc (finput) == 'n'
&& getlc (finput) == 'e'
- && (isspace (c = getlc (finput))))
+ && (c = getlc (finput), ISSPACE (c)))
{
#if 0 /*def DWARF_DEBUGGING_INFO*/
if (c != '\n'
&& getlc (finput) == 'd'
&& getlc (finput) == 'e'
&& getlc (finput) == 'f'
- && (isspace (c = getlc (finput))))
+ && (c = getlc (finput), ISSPACE (c)))
{
#if 0 /*def DWARF_DEBUGGING_INFO*/
if (c != '\n'
&& getlc (finput) == 't'
&& ((c = getlc (finput)) == ' ' || c == '\t'))
{
- /* #ident. The pedantic warning is now in cccp.c. */
+ /* #ident. The pedantic warning is now in cpp. */
/* Here we have just seen `#ident '.
A string constant should follow. */
/* Something follows the #; read a token. */
- if (isdigit(c))
+ if (ISDIGIT(c))
{
int old_lineno = lineno;
int used_up = 0;
{
l = l * 10 + (c - '0'); /* FIXME Not portable */
c = getlc(finput);
- } while (isdigit(c));
+ } while (ISDIGIT(c));
/* subtract one, because it is the following line that
gets the specified number */
/* `1' after file name means entering new file.
`2' after file name means just left a file. */
- if (isdigit (c))
+ if (ISDIGIT (c))
{
if (c == '1')
{
/* collect token into tokenbuf for later analysis */
while (TRUE)
{
- if (isspace (c) || c == '<')
+ if (ISSPACE (c) || c == '<')
break;
obstack_1grow (&temporary_obstack, c);
c = input ();
{
cursor = tokenbuf;
c = *cursor;
- if (!isalpha (c) && c != '_')
+ if (!ISALPHA (c) && c != '_')
{
if (pass == 1)
error ("invalid value follows `=' in compiler directive");
}
for (cursor = &tokenbuf[1]; *cursor != '\0'; cursor++)
- if (isalpha (*cursor) || *cursor == '_' || isdigit (*cursor))
+ if (ISALPHA ((unsigned char) *cursor) || *cursor == '_' ||
+ ISDIGIT (*cursor))
continue;
else
{
*/
void
register_seize_path (path)
- char *path;
+ const char *path;
{
int pathlen = strlen (path);
char *new_path = (char *)xmalloc (pathlen + 1);
static int
yywrap ()
{
- extern char *strchr ();
extern char *chill_real_input_filename;
- tree node;
close_input_file (input_filename);
if (next_file_to_seize && !grant_only_flag)
{
FILE *grt_in = NULL;
- char *seizefile_name_chars
+ const char *seizefile_name_chars
= IDENTIFIER_POINTER (TREE_VALUE (next_file_to_seize));
/* find a seize file, open it. If it's not at the path the
}
if (grt_in == NULL)
- pfatal_with_name (seizefile_name_chars);
+ fatal_io_error ("can't open %s", seizefile_name_chars);
finput = grt_in;
input_filename = seizefile_name_chars;