aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-05-23 13:08:08 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-05-23 13:08:08 +0300
commitbd19f38853dad5a89abada6ee5e7a23c65173894 (patch)
tree57b53cdceeb69db1bb51e8df48eb4f007c6ecb97 /src
parent3ad426f88d274535d7e04e12add72534034ac075 (diff)
downloadpies-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')
-rw-r--r--src/comp.c113
-rw-r--r--src/depmap.c40
-rw-r--r--src/pies.h6
3 files changed, 100 insertions, 59 deletions
diff --git a/src/comp.c b/src/comp.c
index 17832ad..fcd0a14 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -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)
{
- pies_depmap_pos_t pos;
- size_t n;
+ size_t i;
- logmsg_printf (LOG_NOTICE, "%s -> ", comp_array[idx]->tag);
- for (n = depmap_first (depmap, depmap_col, idx, &pos);
- n != (size_t)-1;
- n = depmap_next (depmap, pos))
+ i = idx;
+ do
{
- logmsg_printf (LOG_NOTICE, "%s -> ", comp_array[n]->tag);
+ 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;
}
- depmap_end (pos);
+ 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++)
+ for (i = 0; i < comp_count; i++)
{
- if (comp_array[i])
- {
- printf ("%2lu ", (unsigned long)k);
- for (j = 0; j < comp_count; j++)
- if (comp_array[j])
- printf (" %c ", depmap_isset (depmap, i, j) ? 'X' : ' ');
- printf ("\n");
- k++;
- }
+ printf ("%2lu", (unsigned long)i);
+ for (j = 0; j < comp_count; j++)
+ printf (" %c", depmap_isset (dpm, i, j) ? 'X' : ' ');
+ printf ("\n");
}
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;
diff --git a/src/depmap.c b/src/depmap.c
index 3ea5722..cb50548 100644
--- a/src/depmap.c
+++ b/src/depmap.c
@@ -81,9 +81,9 @@ TC (unsigned *R, int n)
struct pies_depmap
{
- size_t nrows;
- size_t rowlen;
- unsigned r[1];
+ size_t nrows; /* Number of rows (== number of mapped elements) */
+ size_t rowlen; /* Length of a row in words */
+ unsigned r[1]; /* Data rows */
};
pies_depmap_t
@@ -97,11 +97,18 @@ depmap_alloc (size_t count)
return dmap;
}
+/* Return size of a depmap row in bytes */
+static inline size_t
+depmap_row_size (pies_depmap_t dpm)
+{
+ return dpm->rowlen * sizeof (unsigned);
+}
+
pies_depmap_t
depmap_copy (pies_depmap_t dpm)
{
pies_depmap_t copy = depmap_alloc (dpm->nrows);
- memcpy (copy->r, dpm->r, dpm->nrows * dpm->rowlen * sizeof (unsigned));
+ memcpy (copy->r, dpm->r, dpm->nrows * depmap_row_size (dpm));
return copy;
}
@@ -174,21 +181,22 @@ depmap_end (pies_depmap_pos_t pos)
grecs_free (pos);
}
+/* Remove nth row and column from the map */
void
-depmap_clear_all (pies_depmap_t dmap, enum pies_depmap_direction dir,
- size_t coord)
+depmap_remove (pies_depmap_t dmap, size_t n)
{
- size_t i;
-
- switch (dir)
+ if (n < dmap->nrows - 1)
{
- case depmap_row:
- for (i = 0; i < dmap->nrows; i++)
- depmap_clear (dmap, coord, i);
- break;
-
- case depmap_col:
+ size_t i, j;
+
+ /* Remove nth row */
+ memmove (depmap_rowptr (dmap, n), depmap_rowptr (dmap, n + 1),
+ (dmap->nrows - n - 1) * depmap_row_size (dmap));
+ /* Renumber all columns j >= n: j = j - 1 */
for (i = 0; i < dmap->nrows; i++)
- depmap_clear (dmap, i, coord);
+ for (j = n; j < dmap->nrows - 1; j++)
+ (depmap_isset (dmap, i, j + 1) ? depmap_set : depmap_clear)
+ (dmap, i, j);
}
+ dmap->nrows--;
}
diff --git a/src/pies.h b/src/pies.h
index 70d972a..e7e5d71 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -199,6 +199,8 @@ enum pies_comp_mode
#define CF_NULLINPUT 0x200 /* Provide null input stream */
+#define CF_REMOVE 0x400 /* Marked for removal */
+
#define ISCF_TCPMUX(f) ((f) & (CF_TCPMUX | CF_TCPMUXPLUS))
struct prog;
@@ -374,9 +376,7 @@ pies_depmap_t depmap_copy (pies_depmap_t dpm);
void depmap_set (pies_depmap_t dmap, size_t row, size_t col);
int depmap_isset (pies_depmap_t dmap, size_t row, size_t col);
void depmap_clear (pies_depmap_t dmap, size_t row, size_t col);
-
-void depmap_clear_all (pies_depmap_t dmap, enum pies_depmap_direction dir,
- size_t coord);
+void depmap_remove (pies_depmap_t dmap, size_t n);
void depmap_tc (pies_depmap_t dmap);
size_t depmap_first (pies_depmap_t dmap, enum pies_depmap_direction dir,

Return to:

Send suggestions and report system problems to the System administrator.