diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-05-23 13:08:08 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-05-23 13:08:08 +0300 |
commit | bd19f38853dad5a89abada6ee5e7a23c65173894 (patch) | |
tree | 57b53cdceeb69db1bb51e8df48eb4f007c6ecb97 /src/comp.c | |
parent | 3ad426f88d274535d7e04e12add72534034ac075 (diff) | |
download | pies-bd19f38853dad5a89abada6ee5e7a23c65173894.tar.gz pies-bd19f38853dad5a89abada6ee5e7a23c65173894.tar.bz2 |
Revise dependency handling. Correctly display cyclic dependencies.
* src/comp.c (component_log_dep): Remove.
(report_cyclic_dependency): New function.
(comp_array_remove): New function.
(component_build_depmap): Remove erroneous components both from
the component table and dependency map.
(components_dump_depmap): Avoid trailing whitespace in the output.
* src/depmap.c (depmap_clear_all): Remove.
(depmap_remove): New function.
* src/pies.h (CF_REMOVE): New flag.
(depmap_clear_all): Remove prototype.
(depmap_remove): New prototype.
* tests/Makefile.am: Add new test.
* tests/atlocal.in (trimws): New function.
* tests/cyclic.at: New test.
* tests/testsuite.at: Include new test.
Diffstat (limited to 'src/comp.c')
-rw-r--r-- | src/comp.c | 101 |
1 files changed, 67 insertions, 34 deletions
@@ -125,7 +125,7 @@ component_lookup_index (const char *tag) size_t i; for (i = 0; i < comp_count; i++) - if (comp_array[i] && strcmp (comp_array[i]->tag, tag) == 0) + if (strcmp (comp_array[i]->tag, tag) == 0) return i; return -1; } @@ -388,24 +388,54 @@ list_str_cmp (const void *a, const void *b) return safe_strcmp (a, b); } +/* Report cyclic dependency starting at IDX. Mark each element with + CF_REMOVE for subsequent removal. + DP is a transitive closure of depmap. +*/ static void -component_log_dep (size_t idx) +report_cyclic_dependency (pies_depmap_t dp, size_t idx) +{ + size_t i; + + i = idx; + do { - pies_depmap_pos_t pos; size_t n; + pies_depmap_pos_t pos; - logmsg_printf (LOG_NOTICE, "%s -> ", comp_array[idx]->tag); - for (n = depmap_first (depmap, depmap_col, idx, &pos); + logmsg_printf (LOG_NOTICE, "%s -> ", comp_array[i]->tag); + comp_array[i]->flags |= CF_REMOVE; + for (n = depmap_first (depmap, depmap_col, i, &pos); n != (size_t)-1; n = depmap_next (depmap, pos)) { - logmsg_printf (LOG_NOTICE, "%s -> ", comp_array[n]->tag); + if (n == i) + continue; + if (depmap_isset (dp, n, i) && depmap_isset (dp, n, n)) + break; } depmap_end (pos); + + if (n == (size_t)-1) + break; + i = n; + } + while (i != idx); logmsg_printf (LOG_NOTICE, "%s\n", comp_array[idx]->tag); } void +comp_array_remove (size_t i) +{ + struct component *comp = comp_array[i]; + if (i < comp_count - 1) + memmove (&comp_array[i], &comp_array[i+1], + (comp_count - i - 1) * sizeof comp_array[0]); + component_free (comp); + comp_count--; +} + +void component_build_depmap (void) { size_t i; @@ -413,7 +443,7 @@ component_build_depmap (void) free (depmap); depmap = depmap_alloc (comp_count); - for (i = 0; i < comp_count; i++) + for (i = 0; i < comp_count; ) { struct component *comp = comp_array[i]; struct grecs_list_entry *ep; @@ -429,10 +459,8 @@ component_build_depmap (void) _("component %s depends on %s, " "which is not declared"), comp->tag, tag); - component_free (comp); - comp_array[i] = NULL; - depmap_clear_all (depmap, depmap_row, i); - depmap_clear_all (depmap, depmap_col, i); + comp_array_remove (i); + depmap_remove (depmap, i); continue; } depmap_set (depmap, i, tgt); @@ -452,22 +480,30 @@ component_build_depmap (void) } depmap_set (depmap, tgt, i); } + + i++; } dp = depmap_copy (depmap); depmap_tc (dp); for (i = 0; i < comp_count; i++) - if (depmap_isset (dp, i, i)) + if (!(comp_array[i]->flags & CF_REMOVE) && depmap_isset (dp, i, i)) { logmsg (LOG_ERR, _("component %s depends on itself"), comp_array[i]->tag); - component_log_dep (i); - component_free (comp_array[i]); - comp_array[i] = NULL; - depmap_clear_all (depmap, depmap_row, i); - depmap_clear_all (depmap, depmap_col, i); - continue; + report_cyclic_dependency (dp, i); + } + + + for (i = 0; i < comp_count;) + if (comp_array[i]->flags & CF_REMOVE) + { + comp_array_remove (i); + depmap_remove (depmap, i); } + else + i++; + free (dp); } @@ -748,30 +784,21 @@ component_get (size_t n) } void -components_dump_depmap (void) +depmap_dump (pies_depmap_t dpm) { - size_t i, j, k; + size_t i, j; printf ("%s:\n", _("Dependency map")); printf (" "); - for (i = k = 0; i < comp_count; i++) - if (comp_array[i]) - { - printf (" %2lu", (unsigned long)k); - k++; - } + for (i = 0; i < comp_count; i++) + printf (" %2lu", (unsigned long)i); printf ("\n"); - for (i = k = 0; i < comp_count; i++) - { - if (comp_array[i]) + for (i = 0; i < comp_count; i++) { - printf ("%2lu ", (unsigned long)k); + printf ("%2lu", (unsigned long)i); for (j = 0; j < comp_count; j++) - if (comp_array[j]) - printf (" %c ", depmap_isset (depmap, i, j) ? 'X' : ' '); + printf (" %c", depmap_isset (dpm, i, j) ? 'X' : ' '); printf ("\n"); - k++; - } } printf ("\n%s:\n", _("Legend")); for (i = 0; i < comp_count; i++) @@ -779,6 +806,12 @@ components_dump_depmap (void) } void +components_dump_depmap (void) +{ + depmap_dump (depmap); +} + +void component_trace (size_t idx, enum pies_depmap_direction dir) { pies_depmap_pos_t pos; |