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