--- gcc/cpplib.h.orig Mon Feb 9 13:23:51 2004 +++ gcc/cpplib.h Thu Apr 29 12:24:10 2004 @@ -630,6 +630,7 @@ #define CPP_N_DECIMAL 0x0100 #define CPP_N_HEX 0x0200 #define CPP_N_OCTAL 0x0400 +#define CPP_N_BINARY 0x0800 #define CPP_N_UNSIGNED 0x1000 /* Properties. */ #define CPP_N_IMAGINARY 0x2000 --- gcc/cppexp.c.orig Thu Feb 12 00:52:56 2004 +++ gcc/cppexp.c Thu Apr 29 12:29:40 2004 @@ -22,6 +22,9 @@ #include "system.h" #include "cpplib.h" #include "cpphash.h" +#include "flags.h" +#include "coretypes.h" +#include "toplev.h" #define PART_PRECISION (sizeof (cpp_num_part) * CHAR_BIT) #define HALF_MASK (~(cpp_num_part) 0 >> (PART_PRECISION / 2)) @@ -75,6 +78,9 @@ #define SYNTAX_ERROR2(msgid, arg) \ do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg); goto syntax_error; } \ while(0) +#define SYNTAX_ERROR3(msgid, arg1, arg2) \ + do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg1, arg2); goto syntax_error; } \ + while(0) /* Subroutine of cpp_classify_number. S points to a float suffix of length LEN, possibly zero. Returns 0 for an invalid suffix, or a @@ -171,6 +177,11 @@ radix = 16; str++; } + else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == '1')) + { + radix = 2; + str++; + } } /* Now scan for a well-formed integer or float. */ @@ -209,7 +220,8 @@ radix = 10; if (max_digit >= radix) - SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit); + SYNTAX_ERROR3 ("invalid digit \"%c\" in %s constant", '0' + max_digit, + radix == 2? "binary": "octal"); if (float_flag != NOT_FLOAT) { @@ -288,11 +300,16 @@ if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile)) cpp_error (pfile, CPP_DL_PEDWARN, "imaginary constants are a GCC extension"); + if (radix == 2 && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "binary constants are a GCC extension"); if (radix == 10) result |= CPP_N_DECIMAL; else if (radix == 16) result |= CPP_N_HEX; + else if (radix == 2) + result |= CPP_N_BINARY; else result |= CPP_N_OCTAL; @@ -341,6 +358,11 @@ else if ((type & CPP_N_RADIX) == CPP_N_HEX) { base = 16; + p += 2; + } + else if ((type & CPP_N_RADIX) == CPP_N_BINARY) + { + base = 2; p += 2; } --- gcc/doc/extend.texi.orig Wed Jun 9 20:31:59 2004 +++ gcc/doc/extend.texi Wed Jul 7 20:51:58 2004 @@ -475,6 +475,7 @@ * Pragmas:: Pragmas accepted by GCC. * Unnamed Fields:: Unnamed struct/union fields within structs/unions. * Thread-Local:: Per-thread variables. +* Binary constants:: Binary constants using the `0b' prefix. @end menu @node Statement Exprs @@ -7648,6 +7649,26 @@ Non-@code{static} members shall not be @code{__thread}. @end quotation @end itemize + +@node Binary constants +@section Binary constants using the `0b' prefix +@cindex Binary constants using the `0b' prefix + +@emph{Note:} This is currently a private extension of AVR-GCC. + +Integer constants can be written as binary constants, consisting of a +sequence of `0' and `1' digits, prefixed by `0b'. This is +particularly useful in environments that operate a lot on the +bit-level (like microcontrollers). + +The following statements are identical: + +@smallexample +i = 42; +i = 0x2a; +i = 052; +i = 0b101010; +@end smallexample @node C++ Extensions @chapter Extensions to the C++ Language