diff options
Diffstat (limited to 'src/comp.c')
-rw-r--r-- | src/comp.c | 113 |
1 files changed, 73 insertions, 40 deletions
@@ -122,13 +122,13 @@ component_lookup_tag (int idx, const char *tag) ssize_t 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; } struct component * component_create (const char *name) @@ -385,38 +385,68 @@ mark_prog (struct prog *prog, void *data) static int 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; pies_depmap_t dp; 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; if (comp->prereq) for (ep = comp->prereq->head; ep; ep = ep->next) @@ -426,16 +456,14 @@ component_build_depmap (void) if (tgt < 0) { logmsg (LOG_ERR, _("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); } if (comp->depend) @@ -449,28 +477,36 @@ component_build_depmap (void) _("undefined component %s depends on %s"), tag, comp->tag); continue; } 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); } void component_config_commit (void) { @@ -745,43 +781,40 @@ component_get (size_t n) if (n >= comp_count) return NULL; return comp_array[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++) printf ("%2lu: %s\n", (unsigned long)i, comp_array[i]->tag); } void +components_dump_depmap (void) +{ + depmap_dump (depmap); +} + +void component_trace (size_t idx, enum pies_depmap_direction dir) { pies_depmap_pos_t pos; size_t n; int delim = ':'; |