]> git.draconx.ca Git - cdecl99.git/blobdiff - src/normalize.c
Hand-code the normalized specifier ordering.
[cdecl99.git] / src / normalize.c
index e6502d2d951123172ee691b9a35e3add8bb2f339..eac71f3ae12ba6c25c8e67cb7e44349bb8da32e8 100644 (file)
 #include "cdecl-internal.h"
 
 /*
- * Totally order the declaration specifier types by defining an injection into
- * the natural numbers.
+ * Partially order the declaration specifiers by assigning each specifier
+ * type an appropriate integer value.  These values need not be unique for
+ * specifiers that never appear together.
+ *
+ * This implementation relies implicitly on the specific enumeration values.
+ * These values are expected to be stable as they are exposed library API.
  */
-static unsigned order_spec(struct cdecl_declspec *spec)
+static int order_spec(const struct cdecl_declspec *spec)
 {
-       switch (spec->type) {
-#      include "ordspecs.h"
-       default:
-               assert(0);
+       unsigned kind = cdecl_spec_kind(spec);
+       unsigned ret = spec->type;
+
+       /* General sequence: storage, function, qualifier, type */
+       switch (kind) {
+       case CDECL_SPEC_QUAL:
+               ret |= CDECL_SPEC_FUNC;
+               break;
+       case CDECL_SPEC_TYPE:
+               /* Manually reorder some elements that are in the wrong place */
+               switch (ret) {
+               case CDECL_TYPE_INT:
+                       ret += 2; /* OK because "float int" is invalid. */
+                       break;
+               case CDECL_TYPE_SIGNED:
+               case CDECL_TYPE_UNSIGNED:
+                       ret = CDECL_TYPE_VOID;
+                       break;
+               }
+               ret |= CDECL_SPEC_FUNC|CDECL_SPEC_QUAL;
        }
+
+       return ret;
 }
 
-static int compare_specs(struct cdecl_declspec *a, struct cdecl_declspec *b)
+static int compare_specs(const struct cdecl_declspec *a,
+                         const struct cdecl_declspec *b)
 {
        return order_spec(a) - order_spec(b);
 }