* cpplib.c (struct pragma_entry): New structure.
(pragma_dispatch): Pragma dispatcher.
(top_pragmas, gcc_pragmas): New static variables.
(do_pragma): Use pragma_dispatch.
(do_pragma_gcc): New pragma handler.
* cpp.texi: Update.
From-SVN: r34663
+2000-06-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cpplib.c (struct pragma_entry): New structure.
+ (pragma_dispatch): Pragma dispatcher.
+ (top_pragmas, gcc_pragmas): New static variables.
+ (do_pragma): Use pragma_dispatch.
+ (do_pragma_gcc): New pragma handler.
+ * cpp.texi: Update.
+
2000-06-23 Jakub Jelinek <jakub@redhat.com>
* calls.c (compute_argument_addresses): Force stack slots into
@samp{-isystem}, @samp{-I} wins; it is as if the @samp{-isystem} option
had never been specified at all.
-@findex #pragma system_header
-There is also a directive, @samp{#pragma system_header}, which tells GCC
+@findex #pragma GCC system_header
+There is also a directive, @samp{#pragma GCC system_header}, which tells GCC
to consider the rest of the current include file a system header, no
matter where it was found. Code that comes before the @samp{#pragma} in
the file will not be affected.
-@samp{#pragma system_header} has no effect in the primary source file.
+@samp{#pragma GCC system_header} has no effect in the primary source file.
@node Macros, Conditionals, Header Files, Top
@section Macros
@node Poisoning, Macro Pitfalls, Redefining, Macros
@subsection Poisoning Macros
@cindex poisoning macros
+@findex #pragma GCC poison
+@findex #pragma poison
Sometimes, there is an identifier that you want to remove completely
from your program, and make sure that it never creeps back in. To
-enforce this, the @samp{#pragma poison} directive can be used.
-@samp{#pragma poison} is followed by a list of identifiers to poison,
+enforce this, the @samp{#pragma GCC poison} directive can be used.
+@samp{#pragma GCC poison} is followed by a list of identifiers to poison,
and takes effect for the rest of the source. You cannot @samp{#undef} a
poisoned identifier or test to see if it's defined with @samp{#ifdef}.
For example,
@example
-#pragma poison printf sprintf fprintf
+#pragma GCC poison printf sprintf fprintf
sprintf(some_string, "hello");
@end example
@noindent
will produce an error.
+For backwards compatibility @samp{#pragma poison} is also recognized.
+
@node Macro Pitfalls,, Poisoning, Macros
@subsection Pitfalls and Subtleties of Macros
@cindex problems with macros
some old C programs contain such lines.
@findex #pragma
+@findex #pragma GCC
+
The ANSI standard specifies that the effect of the @samp{#pragma}
-directive is implementation-defined. In the GNU C preprocessor,
-@samp{#pragma} directives are not used, except for @samp{#pragma once}
-(@pxref{Once-Only}). However, they are left in the preprocessor output,
-so they are available to the compilation pass.
+directive is implementation-defined. The GNU C preprocessor recognizes
+some pragmas, and passes unrecognized ones through to the preprocessor
+output, so they are available to the compilation pass. GNU C preprocessor
+pragmas are of the form @samp{#pragma GCC ...}. For backwards
+compatibility previously supported pragmas are also recognized without
+the @samp{GCC}, however that use is deprecated.
@findex #ident
The @samp{#ident} directive is supported for compatibility with certain
/* Sub-handlers for the pragmas needing treatment here.
They return 1 if the token buffer is to be popped, 0 if not. */
+struct pragma_entry
+{
+ char const *name;
+ int (*handler) PARAMS ((cpp_reader *));
+};
+
+static int pragma_dispatch
+ PARAMS ((cpp_reader *, const struct pragma_entry *, U_CHAR *, size_t));
static int do_pragma_once PARAMS ((cpp_reader *));
static int do_pragma_implementation PARAMS ((cpp_reader *));
static int do_pragma_poison PARAMS ((cpp_reader *));
static int do_pragma_system_header PARAMS ((cpp_reader *));
static int do_pragma_default PARAMS ((cpp_reader *));
+static int do_pragma_gcc PARAMS ((cpp_reader *));
+
+static const struct pragma_entry top_pragmas[] =
+{
+ {"once", do_pragma_once},
+ {"implementation", do_pragma_implementation},
+ {"poison", do_pragma_poison},
+ {"system_header", do_pragma_system_header},
+ {"GCC", do_pragma_gcc},
+ {NULL, do_pragma_default}
+};
+
+static const struct pragma_entry gcc_pragmas[] =
+{
+ {"implementation", do_pragma_implementation},
+ {"poison", do_pragma_poison},
+ {"system_header", do_pragma_system_header},
+ {NULL, do_pragma_default}
+};
+
+static int pragma_dispatch (pfile, table, p, len)
+ cpp_reader *pfile;
+ const struct pragma_entry *table;
+ U_CHAR *p;
+ size_t len;
+{
+ for (; table->name; table++)
+ if (strlen (table->name) == len && !memcmp (p, table->name, len))
+ return (*table->handler) (pfile);
+ return (*table->handler) (pfile);
+}
static int
do_pragma (pfile)
U_CHAR *buf;
int pop;
enum cpp_ttype token;
+ size_t len;
here = CPP_WRITTEN (pfile);
CPP_PUTS (pfile, "#pragma ", 8);
}
buf = pfile->token_buffer + key;
+ len = CPP_WRITTEN (pfile) - key;
CPP_PUTC (pfile, ' ');
-#define tokis(x) !strncmp((char *) buf, x, sizeof(x) - 1)
- if (tokis ("once"))
- pop = do_pragma_once (pfile);
- else if (tokis ("implementation"))
- pop = do_pragma_implementation (pfile);
- else if (tokis ("poison"))
- pop = do_pragma_poison (pfile);
- else if (tokis ("system_header"))
- pop = do_pragma_system_header (pfile);
- else
- pop = do_pragma_default (pfile);
-#undef tokis
+ pop = pragma_dispatch (pfile, top_pragmas, buf, len);
if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
goto skip;
return 0;
}
+static int
+do_pragma_gcc (pfile)
+ cpp_reader *pfile;
+{
+ long key;
+ enum cpp_ttype token;
+ U_CHAR *buf;
+ size_t len;
+
+ key = CPP_WRITTEN (pfile);
+ token = _cpp_get_directive_token (pfile);
+ if (token != CPP_NAME)
+ return token == CPP_VSPACE;
+
+ buf = pfile->token_buffer + key;
+ len = CPP_WRITTEN (pfile) - key;
+ CPP_PUTC (pfile, ' ');
+
+ return pragma_dispatch (pfile, gcc_pragmas, buf, len);
+}
+
static int
do_pragma_once (pfile)
cpp_reader *pfile;