]> git.draconx.ca Git - cdecl99.git/blob - src/typemap.c
Kill typemap_is_valid.
[cdecl99.git] / src / typemap.c
1 #include <stdio.h>
2 #include <stdbool.h>
3 #include "cdecl.h"
4 #include "typemap.h"
5
6 /*
7  * We can represent type specifiers as a bitmap, which gives us a finite
8  * list of acceptable bitmap values according to the C standard.  However,
9  * the "long" specifier is allowed to occur more than once, but only at most
10  * 2 times.  Treat it as a special case, assigning an unused bit to represent
11  * the second long.
12  */
13 #define CDECL_TYPE_LLONG 31
14
15 static unsigned long add_typespec(unsigned long map, struct cdecl_declspec *s)
16 {
17         if (s->type >= CDECL_TYPE_LLONG) {
18                 fprintf(stderr, "invalid type specifier\n");
19                 return -1;
20         }
21
22         if (s->type == CDECL_TYPE_LONG) {
23                 if (map & (1ul<<CDECL_TYPE_LLONG)) {
24                         fprintf(stderr, "too many long specifiers\n");
25                         return -1;
26                 } else if (map & (1ul<<CDECL_TYPE_LONG)) {
27                         return map | (1ul<<CDECL_TYPE_LLONG);
28                 }
29         }
30
31         if (map & (1ul<<s->type)) {
32                 fprintf(stderr, "duplicate type specifier\n");
33                 return -1;
34         }
35
36         return map | (1ul<<s->type);
37 }
38
39 unsigned long cdecl__build_typemap(struct cdecl_declspec *s)
40 {
41         unsigned long map = 0;
42
43         for (struct cdecl_declspec *c = s; c; c = c->next) {
44                 if (cdecl_spec_kind(c) != CDECL_SPEC_TYPE)
45                         continue;
46
47                 map = add_typespec(map, c);
48                 if (map == -1)
49                         return -1;
50         }
51
52         switch (map) {
53         case 0:
54                 fprintf(stderr, "no type specifiers\n");
55                 return -1;
56 #       include "validtypes.h"
57                 return map;
58         default:
59                 fprintf(stderr, "conflicting type specifiers\n");
60                 return -1;
61         }
62 }