c-common.c (enum format_type): Add format_type_error.
authorJoseph Myers <jsm28@cam.ac.uk>
Tue, 9 Jan 2001 22:51:05 +0000 (22:51 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Tue, 9 Jan 2001 22:51:05 +0000 (22:51 +0000)
* c-common.c (enum format_type): Add format_type_error.
(decode_format_type): New function.
(decl_attributes): Use it.
(format_kind_info): Adjust comment.

From-SVN: r38843

gcc/ChangeLog
gcc/c-common.c

index e7cb0d24badb54923109960e9b8c72a28be48dc8..3a8aea6051384885c187cbae455fb599d1b3e91a 100644 (file)
@@ -1,3 +1,10 @@
+2001-01-09  Joseph S. Myers  <jsm28@cam.ac.uk>
+
+       * c-common.c (enum format_type): Add format_type_error.
+       (decode_format_type): New function.
+       (decl_attributes): Use it.
+       (format_kind_info): Adjust comment.
+
 2001-01-09  David O'Brien  <obrien@BSDi.com>
 
        * config.gcc (*-*-gnu*, i[34567]86-*-elf*, i[34567]86-*-linux*libc1,
index 98d96e2a555e2016ebaab12aa88b448b7fb0e5cb..e8108f3ecec7d90c32ce31b7de2f1cf11d4c9295 100644 (file)
@@ -251,12 +251,16 @@ enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
            A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS, A_MALLOC,
            A_NO_LIMIT_STACK, A_PURE};
 
+/* This must be in the same order as format_types, with format_type_error
+   last.  */
 enum format_type { printf_format_type, scanf_format_type,
-                  strftime_format_type, strfmon_format_type };
+                  strftime_format_type, strfmon_format_type,
+                  format_type_error };
 
 static void add_attribute              PARAMS ((enum attrs, const char *,
                                                 int, int, int));
 static void init_attributes            PARAMS ((void));
+static enum format_type decode_format_type     PARAMS ((const char *));
 static void record_function_format     PARAMS ((tree, tree, enum format_type,
                                                 int, int));
 static void record_international_format        PARAMS ((tree, tree, int));
@@ -970,17 +974,9 @@ decl_attributes (node, attributes, prefix_attributes)
              {
                const char *p = IDENTIFIER_POINTER (format_type_id);
 
-               if (!strcmp (p, "printf") || !strcmp (p, "__printf__"))
-                 format_type = printf_format_type;
-               else if (!strcmp (p, "scanf") || !strcmp (p, "__scanf__"))
-                 format_type = scanf_format_type;
-               else if (!strcmp (p, "strftime")
-                        || !strcmp (p, "__strftime__"))
-                 format_type = strftime_format_type;
-               else if (!strcmp (p, "strfmon")
-                        || !strcmp (p, "__strfmon__"))
-                 format_type = strfmon_format_type;
-               else
+               format_type = decode_format_type (p);
+
+               if (format_type == format_type_error)
                  {
                    warning ("`%s' is an unrecognized format function type", p);
                    continue;
@@ -1512,7 +1508,8 @@ typedef struct
 /* Structure describing a particular kind of format processed by GCC.  */
 typedef struct
 {
-  /* The name of this kind of format, for use in diagnostics.  */
+  /* The name of this kind of format, for use in diagnostics.  Also
+     the name of the attribute (without preceding and following __).  */
   const char *name;
   /* Specifications of the length modifiers accepted; possibly NULL.  */
   const format_length_info *length_char_specs;
@@ -2025,6 +2022,30 @@ init_function_format_info ()
     }
 }
 
+/* Decode a format type from a string, returning the type, or
+   format_type_error if not valid, in which case the caller should print an
+   error message.  */
+static enum format_type
+decode_format_type (s)
+     const char *s;
+{
+  int i;
+  int slen;
+  slen = strlen (s);
+  for (i = 0; i < (int) format_type_error; i++)
+    {
+      int alen;
+      if (!strcmp (s, format_types[i].name))
+       break;
+      alen = strlen (format_types[i].name);
+      if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
+         && s[slen - 1] == '_' && s[slen - 2] == '_'
+         && !strncmp (s + 2, format_types[i].name, alen))
+       break;
+    }
+  return ((enum format_type) i);
+}
+
 /* Record information for argument format checking.  FUNCTION_IDENT is
    the identifier node for the name of the function to check (its decl
    need not exist yet).