/* * Copyright © 2011 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 #include /* 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; uintmax_t length; } array; struct cdecl_function { struct cdecl *parameters; _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 inline int cdecl_spec_kind(struct cdecl_declspec *spec) { return spec->type & ~(CDECL_SPEC_TYPE-1u); } static inline _Bool cdecl_is_abstract(struct cdecl_declarator *d) { while (d->child) d = d->child; return d->type != CDECL_DECL_IDENT; } /* Error handling. */ enum { CDECL_ENOMEM, CDECL_ENOPARSE, }; struct cdecl_error { unsigned code; const char *str; }; const struct cdecl_error *cdecl_get_error(void); #endif