The only remaining meaningful difference between the cdecl_parse_decl
and cdecl_parse_english implementations is the function-simplification
passes are only done for cdecl_parse_decl.
We can easily just make those conditional in a common parser function,
to reduce code duplication.
-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_declspec *norm_specs;
- struct cdecl *decl;
-
- if (!(decl = do_parse(declstr, false)))
- return NULL;
- * 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);
*/
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;
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))
if (!forall_declarators(i, check_parameters))
if (!forall_declarators(i, check_rettypes))
if (!forall_declarators(i, check_rettypes))
if (!forall_declarators(i, check_arrays))
if (!forall_declarators(i, check_arrays))
if (!forall_declarators(i, normalize_specs))
if (!forall_declarators(i, normalize_specs))
if (!forall_declarators(i, check_qualifiers))
if (!forall_declarators(i, check_qualifiers))
if (!valid_declspecs(i, true))
if (!valid_declspecs(i, true))
if (cdecl_is_abstract(i->declarators)
&& (i != decl || i->next)) {
cdecl__errmsg(CDECL__EDECLTYPE);
if (cdecl_is_abstract(i->declarators)
&& (i != decl || i->next)) {
cdecl__errmsg(CDECL__EDECLTYPE);
- return decl;
-err:
- cdecl__free(decl);
- return NULL;
-struct cdecl *cdecl_parse_english(const char *english)
+static struct cdecl *parse_common(const char *str, int english_mode)
- if (!(decl = do_parse(english, true)))
+ if (!(decl = do_parse(str, english_mode)))
- 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;
-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)
}
void cdecl_free(struct cdecl *decl)