X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/8b46a260a9af1e1cd07ae51924022724f73aa830..bbfdea24b2b940031e86e990bc457785dd378b58:/src/cdecl.h diff --git a/src/cdecl.h b/src/cdecl.h index 6055ea8..11e0099 100644 --- a/src/cdecl.h +++ b/src/cdecl.h @@ -1,14 +1,32 @@ +/* + * 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 CEDCL_H_ +#define CDECL_H_ #include +#include /* Declaration specifier kinds. */ enum { - CDECL_SPEC_TYPE = 0, - CDECL_SPEC_STOR = 256, - CDECL_SPEC_QUAL = 512, - CDECL_SPEC_FUNC = 1024, + CDECL_SPEC_TYPE = 256, + CDECL_SPEC_STOR = 512, + CDECL_SPEC_QUAL = 1024, + CDECL_SPEC_FUNC = 2048, }; enum { @@ -23,6 +41,7 @@ enum { CDECL_TYPE_UNSIGNED, CDECL_TYPE_BOOL, CDECL_TYPE_COMPLEX, + CDECL_TYPE_IMAGINARY, CDECL_TYPE_STRUCT, CDECL_TYPE_UNION, CDECL_TYPE_ENUM, @@ -40,11 +59,16 @@ enum { /* 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; @@ -52,26 +76,56 @@ struct cdecl { } *specifiers; struct cdecl_declarator { - struct cdecl_declarator *next; + struct cdecl_declarator *child; unsigned type; union { char *ident; struct cdecl_pointer { - struct cdecl_declspec *qualifiers; - struct cdecl_declarator *declarator; + 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(const struct cdecl_declspec *spec) +{ + return spec->type & ~(CDECL_SPEC_TYPE-1u); +} -static inline int cdecl_spec_kind(struct cdecl_declspec *spec) +static inline _Bool cdecl_is_abstract(const struct cdecl_declarator *d) { - return spec->type & ~0xffu; + 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