/* * Copyright © 2011, 2021, 2023-2024 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CDECL_H_ #define CDECL_H_ #include /* for size_t */ #if __GNUC__ # define CDECL__INLINE __inline #else # define CDECL__INLINE inline #endif /* Compatibility typedefs */ #if HAVE__BOOL typedef _Bool cdecl_bool; #else typedef signed char cdecl_bool; #endif #if HAVE_UNSIGNED_LONG_LONG_INT typedef unsigned long long cdecl_uintmax; #elif HAVE_UNSIGNED___INT64 typedef unsigned __int64 cdecl_uintmax; #else typedef unsigned long cdecl_uintmax; #endif /* Declaration specifier kinds. */ enum { CDECL_SPEC_TYPE = 256, CDECL_SPEC_STOR = 512, CDECL_SPEC_QUAL = 1024, CDECL_SPEC_FUNC = 2048 }; enum { CDECL_TYPE_VOID = CDECL_SPEC_TYPE, CDECL_TYPE_CHAR, CDECL_TYPE_SHORT, CDECL_TYPE_INT, CDECL_TYPE_LONG, CDECL_TYPE_FLOAT, CDECL_TYPE_DOUBLE, CDECL_TYPE_SIGNED, CDECL_TYPE_UNSIGNED, CDECL_TYPE_BOOL, CDECL_TYPE_COMPLEX, CDECL_TYPE_IMAGINARY, CDECL_TYPE_STRUCT, CDECL_TYPE_UNION, CDECL_TYPE_ENUM, CDECL_TYPE_IDENT, CDECL_STOR_TYPEDEF = CDECL_SPEC_STOR, CDECL_STOR_EXTERN, CDECL_STOR_STATIC, CDECL_STOR_AUTO, CDECL_STOR_REGISTER, CDECL_QUAL_RESTRICT = CDECL_SPEC_QUAL, CDECL_QUAL_VOLATILE, CDECL_QUAL_CONST, CDECL_FUNC_INLINE = CDECL_SPEC_FUNC }; /* Declarator types. */ enum { CDECL_DECL_NULL, CDECL_DECL_IDENT, CDECL_DECL_POINTER, CDECL_DECL_ARRAY, CDECL_DECL_FUNCTION }; struct cdecl { struct cdecl *next; struct cdecl_declspec { struct cdecl_declspec *next; unsigned type; char *ident; } *specifiers; struct cdecl_declarator { struct cdecl_declarator *child; unsigned type; union { char *ident; struct cdecl_pointer { struct cdecl_declspec *qualifiers; } pointer; struct cdecl_array { char *vla; cdecl_uintmax length; } array; struct cdecl_function { struct cdecl *parameters; cdecl_bool variadic; } function; } u; } *declarators; }; struct cdecl *cdecl_parse_decl(const char *declstr); struct cdecl *cdecl_parse_english(const char *english); void cdecl_free(struct cdecl *decl); size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl); size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl); static CDECL__INLINE int cdecl_spec_kind(const struct cdecl_declspec *spec) { return spec->type & ~(CDECL_SPEC_TYPE-1u); } static CDECL__INLINE int cdecl_is_abstract(const struct cdecl_declarator *d) { while (d->child) d = d->child; return d->type != CDECL_DECL_IDENT; } /* Error handling. */ enum { CDECL_ENOMEM = 1, CDECL_ENOPARSE, /* Obsolete error codes (no longer returned by the library) */ CDECL_EBADARRAY, CDECL_EBADDECL, CDECL_EBADPARAMS, CDECL_EBADPOINTER, CDECL_EBADQUAL, CDECL_EBADRETURN, CDECL_EBADSTOR, CDECL_EBADTYPE, CDECL_ENOTFUNC, CDECL_EVOIDPARAM }; struct cdecl_error { unsigned code; const char *str; }; const struct cdecl_error *cdecl_get_error(void); #endif