#include #include #include "cdecl.h" #include "typemap.h" #include "parse.h" #include "scan.h" static int verify_declspecs(struct cdecl_declspec *s) { unsigned num_storage = 0; unsigned long typemap; typemap = cdecl__build_typemap(s); if (typemap == -1) return -1; for (struct cdecl_declspec *c = s; c; c = c->next) { switch (cdecl_spec_kind(c)) { case CDECL_SPEC_TYPE: continue; case CDECL_SPEC_STOR: if (++num_storage > 1) { fprintf(stderr, "too many storage-class specifiers\n"); return -1; } break; case CDECL_SPEC_QUAL: /* * Restrict qualifiers are only valid in the * pointer qualifier list, which isn't checked here. */ if (c->type == CDECL_QUAL_RESTRICT) { fprintf(stderr, "only pointer types can be restrict-qualified.\n"); return -1; } break; case CDECL_SPEC_FUNC: /* * We don't support functions yet. */ fprintf(stderr, "only function declarations may have function specifiers.\n"); return -1; default: abort(); } } return 0; } static int verify_decl(struct cdecl *decl) { return verify_declspecs(decl->specifiers); } struct cdecl *cdecl_parse_decl(const char *declstr) { YY_BUFFER_STATE state; struct cdecl *decl; int rc; state = yy_scan_string(declstr); rc = yyparse(&decl); yy_delete_buffer(state); if (rc != 0) return NULL; rc = verify_decl(decl); if (rc != 0) { cdecl_free(decl); return NULL; } return decl; }