]> git.draconx.ca Git - cdecl99.git/blob - src/cdecl.h
Hand-code the normalized specifier ordering.
[cdecl99.git] / src / cdecl.h
1 /*
2  *  Copyright © 2011 Nick Bowler
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #ifndef CDECL_H_
19 #define CDECL_H_
20
21 #include <stddef.h>
22 #include <stdint.h>
23
24 /* Declaration specifier kinds. */
25 enum {
26         CDECL_SPEC_TYPE = 256,
27         CDECL_SPEC_STOR = 512,
28         CDECL_SPEC_QUAL = 1024,
29         CDECL_SPEC_FUNC = 2048,
30 };
31
32 enum {
33         CDECL_TYPE_VOID = CDECL_SPEC_TYPE,
34         CDECL_TYPE_CHAR,
35         CDECL_TYPE_SHORT,
36         CDECL_TYPE_INT,
37         CDECL_TYPE_LONG,
38         CDECL_TYPE_FLOAT,
39         CDECL_TYPE_DOUBLE,
40         CDECL_TYPE_SIGNED,
41         CDECL_TYPE_UNSIGNED,
42         CDECL_TYPE_BOOL,
43         CDECL_TYPE_COMPLEX,
44         CDECL_TYPE_IMAGINARY,
45         CDECL_TYPE_STRUCT,
46         CDECL_TYPE_UNION,
47         CDECL_TYPE_ENUM,
48         CDECL_TYPE_IDENT,
49         CDECL_STOR_TYPEDEF = CDECL_SPEC_STOR,
50         CDECL_STOR_EXTERN,
51         CDECL_STOR_STATIC,
52         CDECL_STOR_AUTO,
53         CDECL_STOR_REGISTER,
54         CDECL_QUAL_RESTRICT = CDECL_SPEC_QUAL,
55         CDECL_QUAL_VOLATILE,
56         CDECL_QUAL_CONST,
57         CDECL_FUNC_INLINE = CDECL_SPEC_FUNC,
58 };
59
60 /* Declarator types. */
61 enum {
62         CDECL_DECL_NULL,
63         CDECL_DECL_IDENT,
64         CDECL_DECL_POINTER,
65         CDECL_DECL_ARRAY,
66         CDECL_DECL_FUNCTION,
67 };
68
69 struct cdecl {
70         struct cdecl *next;
71
72         struct cdecl_declspec {
73                 struct cdecl_declspec *next;
74                 unsigned type;
75                 char *ident;
76         } *specifiers;
77
78         struct cdecl_declarator {
79                 struct cdecl_declarator *child;
80                 unsigned type;
81                 union {
82                         char *ident;
83                         struct cdecl_pointer {
84                                 struct cdecl_declspec *qualifiers;
85                         } pointer;
86                         struct cdecl_array {
87                                 char *vla;
88                                 uintmax_t length;
89                         } array;
90                         struct cdecl_function {
91                                 struct cdecl *parameters;
92                                 _Bool variadic;
93                         } function;
94                 } u;
95         } *declarators;
96 };
97
98 struct cdecl *cdecl_parse_decl(const char *declstr);
99 struct cdecl *cdecl_parse_english(const char *english);
100 void cdecl_free(struct cdecl *decl);
101
102 size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl);
103 size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl);
104
105 static inline int cdecl_spec_kind(const struct cdecl_declspec *spec)
106 {
107         return spec->type & ~(CDECL_SPEC_TYPE-1u);
108 }
109
110 static inline _Bool cdecl_is_abstract(const struct cdecl_declarator *d)
111 {
112         while (d->child)
113                 d = d->child;
114
115         return d->type != CDECL_DECL_IDENT;
116 }
117
118 /* Error handling. */
119 enum {
120         CDECL_ENOMEM,
121         CDECL_ENOPARSE,
122 };
123
124 struct cdecl_error {
125         unsigned code;
126         const char *str;
127 };
128
129 const struct cdecl_error *cdecl_get_error(void);
130
131 #endif