aboutsummaryrefslogtreecommitdiff
path: root/src/comp.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-10-18 22:20:16 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-10-18 22:20:16 +0300
commitc26297063aa2dad0fecd28791a47a8bffcfc9925 (patch)
tree964990a4dd3c62bf0f25f248518b729403eb3c1a /src/comp.c
parenta7f3e6adb0ffbe56d9b521522d22cf758ee6acb7 (diff)
downloadpies-c26297063aa2dad0fecd28791a47a8bffcfc9925.tar.gz
pies-c26297063aa2dad0fecd28791a47a8bffcfc9925.tar.bz2
Fix cyclic dependecy detection and reporting.
Use modified Floyd-Warshall algorithm for cyclic dependecy detection. The computed next vertex indices are used when reporting the cycles found. This fixes dead loops that occurred in earlier versions when trying to report cycles. One of inputs that caused such behavior is used as a new test in cyclic.at. * src/depmap.c: Rewrite using modified Floyd-Warshall algorithm. (depmap_cycle_detect,depmap_path_free): New functions. * src/comp.c (report_cyclic_dependency): Take struct depmap_path * as argument. (component_build_depmap): Use depmap_cycle_detect to detect cyclic dependencies. (depmap_dump): Special handling for zero-sized depmap. * tests/cyclic.at: Add new test. * src/pies.h (depmap_dim, depmap_free) (depmap_cycle_detect,depmap_path_free): New protos. * NEWS: Document changes.
Diffstat (limited to 'src/comp.c')
-rw-r--r--src/comp.c80
1 files changed, 32 insertions, 48 deletions
diff --git a/src/comp.c b/src/comp.c
index 28d4d6d..09f9611 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -403,44 +403,24 @@ list_str_cmp (const void *a, const void *b)
DP is a transitive closure of depmap.
*/
static void
-report_cyclic_dependency (pies_depmap_t dp, size_t idx)
+report_cyclic_dependency (struct depmap_path *path)
{
- size_t i;
-
- i = idx;
- do
+ struct depmap_path_elem *p;
+ for (p = path->head; p; p = p->next)
{
- size_t n;
- pies_depmap_pos_t 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))
- {
- 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;
+ logmsg_printf (LOG_NOTICE, "%s -> ", comp_array[p->idx]->tag);
+ comp_array[p->idx]->flags |= CF_REMOVE;
}
- while (i != idx);
- logmsg_printf (LOG_NOTICE, "%s\n", comp_array[idx]->tag);
+ logmsg_printf (LOG_NOTICE, "%s\n", comp_array[path->head->idx]->tag);
}
void
component_build_depmap (void)
{
- size_t i;
- pies_depmap_t dp;
-
- free (depmap);
+ struct depmap_path *path;
+ int i;
+
+ depmap_free (depmap);
depmap = depmap_alloc (comp_count);
for (i = 0; i < comp_count; )
{
@@ -482,24 +462,22 @@ component_build_depmap (void)
i++;
}
- dp = depmap_copy (depmap);
- depmap_tc (dp);
- for (i = 0; i < comp_count; 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);
- report_cyclic_dependency (dp, i);
- }
-
-
- for (i = 0; i < comp_count;)
- if (comp_array[i]->flags & CF_REMOVE)
- comp_array_remove (i);
- else
- i++;
-
- free (dp);
+ path = depmap_cycle_detect (depmap);
+ if (path)
+ {
+ struct depmap_path *p;
+
+ logmsg (LOG_ERR, "%s", _("cyclic dependencies detected:"));
+ for (p = path; p; p = p->next)
+ report_cyclic_dependency (p);
+ depmap_path_free (path);
+
+ for (i = 0; i < comp_count;)
+ if (comp_array[i]->flags & CF_REMOVE)
+ comp_array_remove (i);
+ else
+ i++;
+ }
}
void
@@ -806,6 +784,12 @@ depmap_dump (pies_depmap_t dpm)
{
size_t i, j;
+ if (depmap_dim (dpm) == 0)
+ {
+ printf ("%s\n", _("No components defined"));
+ return;
+ }
+
printf ("%s:\n", _("Dependency map"));
printf (" ");
for (i = 0; i < comp_count; i++)

Return to:

Send suggestions and report system problems to the System administrator.