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