return b;
}
+/*
+ * Reverse the order of a "struct cdecl" list, and return the new first
+ * element of the list (i.e., the last element of the original list).
+ */
+static struct cdecl *reverse_decls(struct cdecl *decl)
+{
+ struct cdecl *prev, *next;
+
+ for (prev = NULL; decl; decl = next) {
+ next = decl->next;
+ decl->next = prev;
+ prev = decl;
+ }
+
+ return prev;
+}
+
/*
* Alter an abstract declarator (type name) to declare an identifier instead,
* used by the English parser rules to reduce "identifier as type" sequences.
*/
-static struct cdecl *insert_identifier(struct cdecl *decl, struct parse_item *ident)
+static struct cdecl *
+insert_identifier(struct cdecl *decl, struct parse_item *ident)
{
struct cdecl_declarator *d, **p = &decl->declarators;
semi: | T_SEMICOLON
declaration: declspecs declarators semi {
- $$ = $2;
+ $$ = reverse_decls($2);
$$->specifiers = $1;
};
$$->next = $1;
}
-declarators: declarator_wrap | declarator_wrap T_COMMA declarators {
- $$ = $1;
- $$->next = $3;
+declarators: declarator_wrap | declarators T_COMMA declarator_wrap {
+ $$ = $3;
+ $$->next = $1;
}
declarator_wrap: declarator {
]])
AT_CLEANUP
+
+# Check that we can parse declarations with more than 10000 declarators.
+AT_SETUP([Excessive declarators])
+
+AT_DATA([check.awk],
+[[# We don't need any field splitting, so choose a character that does not
+# appear in C code to avoid tripping over 199-field limit in HP-UX 11 awk.
+BEGIN { FS = "@"; runstart = 0; }
+END { finish_run(NR); }
+
+$0 != lastline {
+ finish_run(NR-1);
+ lastline = $0;
+ runstart = NR;
+ print;
+}
+
+function finish_run(nr) {
+ count = nr - runstart;
+ if (count > 0)
+ print "[repeated " count " more times]";
+}
+]])
+
+a="a"
+for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14; do
+ AS_VAR_APPEND([a], [",$a"])
+done
+
+cat >test.dat <<EOF
+explain int $a
+EOF
+
+AT_CHECK([cdecl99 -f test.dat >test.out; status=$?;
+$AWK -f check.awk test.out
+exit $status], [0],
+[[declare a as int
+[repeated 16383 more times]
+]])
+
+AT_CLEANUP