aboutsummaryrefslogtreecommitdiff
path: root/libctf/testsuite/libctf-lookup/enumerator-iteration.c
diff options
context:
space:
mode:
Diffstat (limited to 'libctf/testsuite/libctf-lookup/enumerator-iteration.c')
-rw-r--r--libctf/testsuite/libctf-lookup/enumerator-iteration.c67
1 files changed, 64 insertions, 3 deletions
diff --git a/libctf/testsuite/libctf-lookup/enumerator-iteration.c b/libctf/testsuite/libctf-lookup/enumerator-iteration.c
index 78cb5a3..9d26421 100644
--- a/libctf/testsuite/libctf-lookup/enumerator-iteration.c
+++ b/libctf/testsuite/libctf-lookup/enumerator-iteration.c
@@ -56,19 +56,40 @@ main (int argc, char *argv[])
if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL)
goto open_err;
- /* Look for all instances of ENUMSAMPLE2_1, and add some new enums to all
+ /* Look for all instances of ENUMSAMPLE2_2, and add some new enums to all
dicts found, to test dynamic enum iteration as well as static.
Add two enums with a different name and constants to any that should
already be there (one hidden), and one with the same constants, but hidden,
to test ctf_lookup_enumerator_next()'s multiple-lookup functionality and
- ctf_lookup_enumerator() in the presence of hidden types. */
+ ctf_lookup_enumerator() in the presence of hidden types.
+
+ This also tests that you can add to enums under iteration without causing
+ disaster. */
printf ("First iteration: addition of enums.\n");
while ((type = ctf_arc_lookup_enumerator_next (ctf, "IENUMSAMPLE2_2", &i,
&val, &fp, &err)) != CTF_ERR)
{
char *foo;
+ int dynadd2_value;
+ int old_dynadd2_flag;
+
+ /* Make sure that getting and setting a garbage flag, and setting one to a
+ garbage value, fails properly. */
+ if (ctf_dict_set_flag (fp, CTF_STRICT_NO_DUP_ENUMERATORS, 666) >= 0
+ || ctf_errno (fp) != ECTF_BADFLAG)
+ fprintf (stderr, "Invalid flag value setting did not fail as it ought to\n");
+
+ if (ctf_dict_set_flag (fp, 0, 1) >= 0 || ctf_errno (fp) != ECTF_BADFLAG)
+ fprintf (stderr, "Invalid flag setting did not fail as it ought to\n");
+
+ if (ctf_dict_get_flag (fp, 0) >= 0 || ctf_errno (fp) != ECTF_BADFLAG)
+ fprintf (stderr, "Invalid flag getting did not fail as it ought to\n");
+
+ /* Set it strict for now. */
+ if (ctf_dict_set_flag (fp, CTF_STRICT_NO_DUP_ENUMERATORS, 1) < 0)
+ goto set_flag_err;
printf ("IENUMSAMPLE2_2 in %s has value %li\n",
foo = ctf_type_aname (fp, type), (long int) val);
@@ -79,8 +100,10 @@ main (int argc, char *argv[])
if (ctf_add_enumerator (fp, type, "DYNADD", counter += 10) < 0)
goto enumerator_add_err;
+
if (ctf_add_enumerator (fp, type, "DYNADD2", counter += 10) < 0)
goto enumerator_add_err;
+ dynadd2_value = counter;
/* Make sure that overlapping enumerator addition fails as it should. */
@@ -88,6 +111,32 @@ main (int argc, char *argv[])
|| ctf_errno (fp) != ECTF_DUPLICATE)
fprintf (stderr, "Duplicate enumerator addition did not fail as it ought to\n");
+ /* Make sure that it still fails if you set an enum value to the value it
+ already has. */
+ if (ctf_add_enumerator (fp, type, "DYNADD2", dynadd2_value) >= 0
+ || ctf_errno (fp) != ECTF_DUPLICATE)
+ fprintf (stderr, "Duplicate enumerator addition did not fail as it ought to\n");
+
+ /* Flip the strict flag and try again. This time, it should succeed. */
+
+ if ((old_dynadd2_flag = ctf_dict_get_flag (fp, CTF_STRICT_NO_DUP_ENUMERATORS)) < 0)
+ goto get_flag_err;
+
+ if (ctf_dict_set_flag (fp, CTF_STRICT_NO_DUP_ENUMERATORS, 0) < 0)
+ goto set_flag_err;
+
+ if (ctf_add_enumerator (fp, type, "DYNADD2", dynadd2_value) < 0)
+ goto enumerator_add_err;
+
+ /* Flip it again and try *again*. This time it should fail again. */
+
+ if (ctf_dict_set_flag (fp, CTF_STRICT_NO_DUP_ENUMERATORS, old_dynadd2_flag) < 0)
+ goto set_flag_err;
+
+ if (ctf_add_enumerator (fp, type, "DYNADD2", dynadd2_value) >= 0
+ || ctf_errno (fp) != ECTF_DUPLICATE)
+ fprintf (stderr, "Duplicate enumerator addition did not fail as it ought to\n");
+
if ((type = ctf_add_enum (fp, CTF_ADD_NONROOT, "ie4_hidden")) == CTF_ERR)
goto enum_add_err;
@@ -104,12 +153,18 @@ main (int argc, char *argv[])
if (ctf_add_enumerator (fp, type, "DYNADD2", counter += 10) < 0)
goto enumerator_add_err;
- /* Look them up via ctf_lookup_enumerator. */
+ /* Look them up via ctf_lookup_enumerator. DYNADD2 should fail because
+ it has duplicate enumerators. */
if (ctf_lookup_enumerator (fp, "DYNADD", &val) == CTF_ERR)
goto enumerator_lookup_err;
printf ("direct lookup: DYNADD value: %i\n", (int) val);
+ if ((err = ctf_lookup_enumerator (fp, "DYNADD2", &val)) >= 0 ||
+ ctf_errno (fp) != ECTF_DUPLICATE)
+ fprintf (stderr, "Duplicate enumerator lookup did not fail as it ought to: %i, %s\n",
+ err, ctf_errmsg (ctf_errno (fp)));
+
if ((type = ctf_lookup_enumerator (fp, "DYNADD3", &val) != CTF_ERR) ||
ctf_errno (fp) != ECTF_NOENUMNAM)
{
@@ -164,4 +219,10 @@ main (int argc, char *argv[])
fprintf (stderr, "Cannot look up enumerator in dict \"%s\": %s\n",
ctf_cuname (fp) ? ctf_cuname (fp) : "(null: parent)", ctf_errmsg (ctf_errno (fp)));
return 1;
+ get_flag_err:
+ fprintf (stderr, "ctf_dict_get_flag failed: %s\n", ctf_errmsg (ctf_errno (fp)));
+ return 1;
+ set_flag_err:
+ fprintf (stderr, "ctf_dict_set_flag failed: %s\n", ctf_errmsg (ctf_errno (fp)));
+ return 1;
}