]> git.draconx.ca Git - cdecl99.git/blob - src/cdecl.h
libcdecl: Prefer __inline in public header with GCC.
[cdecl99.git] / src / cdecl.h
1 /*
2  * Copyright © 2011, 2021, 2023 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 #if __GNUC__
25 #  define CDECL__INLINE __inline
26 #else
27 #  define CDECL__INLINE inline
28 #endif
29
30 /* Compatibility typedefs */
31 #if HAVE__BOOL
32 typedef _Bool cdecl_bool;
33 #else
34 typedef signed char cdecl_bool;
35 #endif
36
37 /* Declaration specifier kinds. */
38 enum {
39         CDECL_SPEC_TYPE = 256,
40         CDECL_SPEC_STOR = 512,
41         CDECL_SPEC_QUAL = 1024,
42         CDECL_SPEC_FUNC = 2048
43 };
44
45 enum {
46         CDECL_TYPE_VOID = CDECL_SPEC_TYPE,
47         CDECL_TYPE_CHAR,
48         CDECL_TYPE_SHORT,
49         CDECL_TYPE_INT,
50         CDECL_TYPE_LONG,
51         CDECL_TYPE_FLOAT,
52         CDECL_TYPE_DOUBLE,
53         CDECL_TYPE_SIGNED,
54         CDECL_TYPE_UNSIGNED,
55         CDECL_TYPE_BOOL,
56         CDECL_TYPE_COMPLEX,
57         CDECL_TYPE_IMAGINARY,
58         CDECL_TYPE_STRUCT,
59         CDECL_TYPE_UNION,
60         CDECL_TYPE_ENUM,
61         CDECL_TYPE_IDENT,
62         CDECL_STOR_TYPEDEF = CDECL_SPEC_STOR,
63         CDECL_STOR_EXTERN,
64         CDECL_STOR_STATIC,
65         CDECL_STOR_AUTO,
66         CDECL_STOR_REGISTER,
67         CDECL_QUAL_RESTRICT = CDECL_SPEC_QUAL,
68         CDECL_QUAL_VOLATILE,
69         CDECL_QUAL_CONST,
70         CDECL_FUNC_INLINE = CDECL_SPEC_FUNC
71 };
72
73 /* Declarator types. */
74 enum {
75         CDECL_DECL_NULL,
76         CDECL_DECL_IDENT,
77         CDECL_DECL_POINTER,
78         CDECL_DECL_ARRAY,
79         CDECL_DECL_FUNCTION
80 };
81
82 struct cdecl {
83         struct cdecl *next;
84
85         struct cdecl_declspec {
86                 struct cdecl_declspec *next;
87                 unsigned type;
88                 char *ident;
89         } *specifiers;
90
91         struct cdecl_declarator {
92                 struct cdecl_declarator *child;
93                 unsigned type;
94                 union {
95                         char *ident;
96                         struct cdecl_pointer {
97                                 struct cdecl_declspec *qualifiers;
98                         } pointer;
99                         struct cdecl_array {
100                                 char *vla;
101                                 uintmax_t length;
102                         } array;
103                         struct cdecl_function {
104                                 struct cdecl *parameters;
105                                 cdecl_bool variadic;
106                         } function;
107                 } u;
108         } *declarators;
109 };
110
111 struct cdecl *cdecl_parse_decl(const char *declstr);
112 struct cdecl *cdecl_parse_english(const char *english);
113 void cdecl_free(struct cdecl *decl);
114
115 size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl);
116 size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl);
117
118 static CDECL__INLINE int cdecl_spec_kind(const struct cdecl_declspec *spec)
119 {
120         return spec->type & ~(CDECL_SPEC_TYPE-1u);
121 }
122
123 static CDECL__INLINE int cdecl_is_abstract(const struct cdecl_declarator *d)
124 {
125         while (d->child)
126                 d = d->child;
127
128         return d->type != CDECL_DECL_IDENT;
129 }
130
131 /* Error handling. */
132 enum {
133         CDECL_ENOMEM = 1,
134         CDECL_ENOPARSE,
135
136         /* Obsolete error codes (no longer returned by the library) */
137         CDECL_EBADARRAY,
138         CDECL_EBADDECL,
139         CDECL_EBADPARAMS,
140         CDECL_EBADPOINTER,
141         CDECL_EBADQUAL,
142         CDECL_EBADRETURN,
143         CDECL_EBADSTOR,
144         CDECL_EBADTYPE,
145         CDECL_ENOTFUNC,
146         CDECL_EVOIDPARAM
147 };
148
149 struct cdecl_error {
150         unsigned code;
151         const char *str;
152 };
153
154 const struct cdecl_error *cdecl_get_error(void);
155
156 #endif