return decl;
}
-struct cdecl *cdecl_parse_decl(const char *declstr)
+static int do_postprocess(struct cdecl *decl, int english_mode)
{
struct cdecl_declspec *norm_specs;
- struct cdecl *decl;
-
- if (!(decl = do_parse(declstr, false)))
- return NULL;
+ struct cdecl *i;
/*
- * Since the top-level specifiers are shared between each top-level
- * declarator, we need to normalize them once and then propagate the
- * new specifier list.
+ * For a C declaration with more than one full declarator, the
+ * specifier list is common to all of them. Normalize it once,
+ * then propagate that to all the linked cdecl structures.
+ *
+ * In english mode, the cdecl structure list always has exactly
+ * one entry so we don't need to do anything differently.
*/
norm_specs = cdecl__normalize_specs(decl->specifiers);
- for (struct cdecl *i = decl; i; i = i->next) {
+ for (i = decl; i; i = i->next)
i->specifiers = norm_specs;
- }
- /* Now perform checks and simplifications on each declarator. */
- for (struct cdecl *i = decl; i; i = i->next) {
- if (!forall_declarators(i, reduce_parentheses))
- goto err;
- if (!forall_declarators(i, simplify_functions))
- goto err;
+ for (i = decl; i; i = i->next) {
+ if (!english_mode) {
+ if (!forall_declarators(i, reduce_parentheses))
+ return 0;
+ if (!forall_declarators(i, simplify_functions))
+ return 0;
+ }
+
if (!forall_declarators(i, check_parameters))
- goto err;
+ return 0;
if (!forall_declarators(i, check_rettypes))
- goto err;
+ return 0;
if (!forall_declarators(i, check_arrays))
- goto err;
+ return 0;
if (!forall_declarators(i, normalize_specs))
- goto err;
+ return 0;
if (!forall_declarators(i, check_qualifiers))
- goto err;
+ return 0;
if (!valid_declspecs(i, true))
- goto err;
+ return 0;
if (cdecl_is_abstract(i->declarators)
&& (i != decl || i->next)) {
cdecl__errmsg(CDECL__EDECLTYPE);
- goto err;
+ return 0;
}
}
- return decl;
-err:
- cdecl__free(decl);
- return NULL;
+ return 1;
}
-struct cdecl *cdecl_parse_english(const char *english)
+static struct cdecl *parse_common(const char *str, int english_mode)
{
struct cdecl *decl;
- if (!(decl = do_parse(english, true)))
+ if (!(decl = do_parse(str, english_mode)))
return NULL;
- for (struct cdecl *i = decl; i; i = i->next) {
- i->specifiers = cdecl__normalize_specs(i->specifiers);
-
- if (!forall_declarators(i, check_parameters))
- goto err;
- if (!forall_declarators(i, check_rettypes))
- goto err;
- if (!forall_declarators(i, check_arrays))
- goto err;
- if (!forall_declarators(i, normalize_specs))
- goto err;
- if (!forall_declarators(i, check_qualifiers))
- goto err;
-
- if (!valid_declspecs(i, true))
- goto err;
+ if (!do_postprocess(decl, english_mode)) {
+ cdecl__free(decl);
+ return NULL;
}
return decl;
-err:
- cdecl__free(decl);
- return NULL;
+}
+
+struct cdecl *cdecl_parse_decl(const char *declstr)
+{
+ return parse_common(declstr, false);
+}
+
+struct cdecl *cdecl_parse_english(const char *english)
+{
+ return parse_common(english, true);
}
void cdecl_free(struct cdecl *decl)