summaryrefslogtreecommitdiff
path: root/gcc/cppexp.c
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.demon.co.uk>2001-05-11 23:48:21 +0000
committerNeil Booth <neil@gcc.gnu.org>2001-05-11 23:48:21 +0000
commitc8a96070172673d05574e3c9fe21e28750610223 (patch)
treeeefc97fe7077fa7f6cfc9bb868638feb3419f0dd /gcc/cppexp.c
parentf42974dc81a20a5ea306fab56faef8c322bf26d2 (diff)
downloadgcc-c8a96070172673d05574e3c9fe21e28750610223.tar.gz
c-lex.c (lex_charconst): Convert into a simple wrapper around cpp_interpret_charconst...
* c-lex.c (lex_charconst): Convert into a simple wrapper around cpp_interpret_charconst, to which most of the code body is moved. * cppexp.c (MAX_CHAR_TYPE_SIZE, MAX_WCHAR_TYPE_SIZE, MAX_LONG_TYPE_SIZE, MAX_INT_TYPE_SIZE, MAX_CHAR_TYPE_MASK, MAX_WCHAR_TYPE_MASK, parse_escape, parse_charconst): Remove. (lex): Use cpp_interpret_charconst. * cpplex.c (parse_escape, read_ucs, cpp_interpret_charconst, hex_digit_value): New functions. (MAX_CHAR_TYPE_SIZE, MAX_WCHAR_TYPE_SIZE): New macros. * cpplib.h (cpp_interpret_charconst): New prototype. * Makefile.in: Update. From-SVN: r41978
Diffstat (limited to 'gcc/cppexp.c')
-rw-r--r--gcc/cppexp.c210
1 files changed, 9 insertions, 201 deletions
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 1231a7e2669..acfa30ee5a4 100644
--- a/gcc/cppexp.c
+++ b/gcc/cppexp.c
@@ -18,37 +18,11 @@ along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Parse a C expression from text in a string */
-
#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "cpphash.h"
-#ifndef MAX_CHAR_TYPE_SIZE
-#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
-#endif
-
-#ifndef MAX_INT_TYPE_SIZE
-#define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
-#endif
-
-#ifndef MAX_LONG_TYPE_SIZE
-#define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
-#endif
-
-#ifndef MAX_WCHAR_TYPE_SIZE
-#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
-#endif
-
-#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
- ? (~(~(HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
- : ~ (HOST_WIDEST_INT) 0)
-
-#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
- ? ~(~(HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
- : ~ (HOST_WIDEST_INT) 0)
-
/* Yield nonzero if adding two numbers with A's and B's signs can yield a
number with SUM's sign, where A, B, and SUM are all C integers. */
#define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
@@ -61,10 +35,7 @@ static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT,
unsigned int,
unsigned HOST_WIDEST_INT));
static struct op parse_number PARAMS ((cpp_reader *, const cpp_token *));
-static struct op parse_charconst PARAMS ((cpp_reader *, const cpp_token *));
static struct op parse_defined PARAMS ((cpp_reader *));
-static HOST_WIDEST_INT parse_escape PARAMS ((cpp_reader *, const U_CHAR **,
- const U_CHAR *, HOST_WIDEST_INT));
static struct op lex PARAMS ((cpp_reader *, int, cpp_token *));
static const unsigned char *op_as_text PARAMS ((cpp_reader *, enum cpp_ttype));
@@ -238,81 +209,6 @@ parse_number (pfile, tok)
return op;
}
-/* Parse and convert a character constant for #if. Understands backslash
- escapes (\n, \031) and multibyte characters (if so configured). */
-static struct op
-parse_charconst (pfile, tok)
- cpp_reader *pfile;
- const cpp_token *tok;
-{
- struct op op;
- HOST_WIDEST_INT result = 0;
- int num_chars = 0;
- int num_bits;
- unsigned int width = MAX_CHAR_TYPE_SIZE;
- HOST_WIDEST_INT mask = MAX_CHAR_TYPE_MASK;
- int max_chars;
- const U_CHAR *ptr = tok->val.str.text;
- const U_CHAR *end = ptr + tok->val.str.len;
-
- int c = -1;
-
- if (tok->type == CPP_WCHAR)
- width = MAX_WCHAR_TYPE_SIZE, mask = MAX_WCHAR_TYPE_MASK;
- max_chars = MAX_LONG_TYPE_SIZE / width;
-
- while (ptr < end)
- {
- c = *ptr++;
- if (c == '\'')
- CPP_ICE ("unescaped ' in character constant");
- else if (c == '\\')
- {
- c = parse_escape (pfile, &ptr, end, mask);
- if (width < HOST_BITS_PER_INT
- && (unsigned int) c >= (unsigned int)(1 << width))
- cpp_pedwarn (pfile,
- "escape sequence out of range for character");
- }
-
- /* Merge character into result; ignore excess chars. */
- if (++num_chars <= max_chars)
- {
- if (width < HOST_BITS_PER_INT)
- result = (result << width) | (c & ((1 << width) - 1));
- else
- result = c;
- }
- }
-
- if (num_chars == 0)
- SYNTAX_ERROR ("empty character constant");
- else if (num_chars > max_chars)
- SYNTAX_ERROR ("character constant too long");
- else if (num_chars != 1)
- cpp_warning (pfile, "multi-character character constant");
-
- /* If char type is signed, sign-extend the constant. */
- num_bits = num_chars * width;
-
- if (pfile->spec_nodes.n__CHAR_UNSIGNED__->type == NT_MACRO
- || ((result >> (num_bits - 1)) & 1) == 0)
- op.value = result & ((unsigned HOST_WIDEST_INT) ~0
- >> (HOST_BITS_PER_WIDEST_INT - num_bits));
- else
- op.value = result | ~((unsigned HOST_WIDEST_INT) ~0
- >> (HOST_BITS_PER_WIDEST_INT - num_bits));
-
- /* This is always a signed type. */
- op.unsignedp = 0;
- op.op = CPP_INT;
- return op;
-
- syntax_error:
- op.op = CPP_ERROR;
- return op;
-}
-
static struct op
parse_defined (pfile)
cpp_reader *pfile;
@@ -405,7 +301,15 @@ lex (pfile, skip_evaluation, token)
case CPP_CHAR:
case CPP_WCHAR:
- return parse_charconst (pfile, token);
+ {
+ unsigned int chars_seen;
+
+ /* This is always a signed type. */
+ op.unsignedp = 0;
+ op.op = CPP_INT;
+ op.value = cpp_interpret_charconst (pfile, token, 1, 0, &chars_seen);
+ return op;
+ }
case CPP_STRING:
case CPP_WSTRING:
@@ -494,102 +398,6 @@ lex (pfile, skip_evaluation, token)
return op;
}
-/* Parse a C escape sequence. STRING_PTR points to a variable
- containing a pointer to the string to parse. That pointer
- is updated past the characters we use. The value of the
- escape sequence is returned.
-
- If \ is followed by 000, we return 0 and leave the string pointer
- after the zeros. A value of 0 does not mean end of string. */
-
-static HOST_WIDEST_INT
-parse_escape (pfile, string_ptr, limit, result_mask)
- cpp_reader *pfile;
- const U_CHAR **string_ptr;
- const U_CHAR *limit;
- HOST_WIDEST_INT result_mask;
-{
- const U_CHAR *ptr = *string_ptr;
- /* We know we have at least one following character. */
- int c = *ptr++;
- switch (c)
- {
- case 'a': c = TARGET_BELL; break;
- case 'b': c = TARGET_BS; break;
- case 'f': c = TARGET_FF; break;
- case 'n': c = TARGET_NEWLINE; break;
- case 'r': c = TARGET_CR; break;
- case 't': c = TARGET_TAB; break;
- case 'v': c = TARGET_VT; break;
-
- case 'e': case 'E':
- if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "non-ISO-standard escape sequence, '\\%c'", c);
- c = TARGET_ESC;
- break;
-
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- {
- unsigned int i = c - '0';
- int count = 0;
- while (++count < 3)
- {
- if (ptr >= limit)
- break;
-
- c = *ptr;
- if (c < '0' || c > '7')
- break;
- ptr++;
- i = (i << 3) + c - '0';
- }
- if (i != (i & result_mask))
- {
- i &= result_mask;
- cpp_pedwarn (pfile, "octal escape sequence out of range");
- }
- c = i;
- break;
- }
-
- case 'x':
- {
- unsigned int i = 0, overflow = 0;
- int digits_found = 0, digit;
- for (;;)
- {
- if (ptr >= limit)
- break;
- c = *ptr;
- if (c >= '0' && c <= '9')
- digit = c - '0';
- else if (c >= 'a' && c <= 'f')
- digit = c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- digit = c - 'A' + 10;
- else
- break;
- ptr++;
- overflow |= i ^ (i << 4 >> 4);
- i = (i << 4) + digit;
- digits_found = 1;
- }
- if (!digits_found)
- cpp_error (pfile, "\\x used with no following hex digits");
- if (overflow | (i != (i & result_mask)))
- {
- i &= result_mask;
- cpp_pedwarn (pfile, "hex escape sequence out of range");
- }
- c = i;
- break;
- }
- }
- *string_ptr = ptr;
- return c;
-}
-
static void
integer_overflow (pfile)
cpp_reader *pfile;