summaryrefslogtreecommitdiffstats
path: root/grub-core/genmoddep.awk
diff options
context:
space:
mode:
Diffstat (limited to 'grub-core/genmoddep.awk')
-rw-r--r--grub-core/genmoddep.awk102
1 files changed, 102 insertions, 0 deletions
diff --git a/grub-core/genmoddep.awk b/grub-core/genmoddep.awk
new file mode 100644
index 0000000..04c2863
--- /dev/null
+++ b/grub-core/genmoddep.awk
@@ -0,0 +1,102 @@
+#! /usr/bin/awk -f
+#
+# Copyright (C) 2006 Free Software Foundation, Inc.
+#
+# This genmoddep.awk is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read symbols' info from stdin.
+BEGIN {
+ error = 0
+}
+
+{
+ if ($1 == "defined") {
+ if ($3 !~ /^\.refptr\./ && $3 in symtab) {
+ printf "%s in %s is duplicated in %s\n", $3, $2, symtab[$3] >"/dev/stderr";
+ error++;
+ }
+ symtab[$3] = $2;
+ modtab[$2] = "" modtab[$2]
+ } else if ($1 == "undefined") {
+ if ($3 in symtab)
+ modtab[$2] = modtab[$2] " " symtab[$3];
+ else if ($3 != "__gnu_local_gp" && $3 != "_gp_disp") {
+ printf "%s in %s is not defined\n", $3, $2 >"/dev/stderr";
+ error++;
+ }
+ }
+ else {
+ printf "error: %u: unrecognized input format\n", NR >"/dev/stderr";
+ error++;
+ }
+}
+
+# Output the result.
+END {
+ if (error >= 1)
+ exit 1;
+
+ total_depcount = 0
+
+ for (mod in modtab) {
+ # Remove duplications.
+ split(modtab[mod], depmods, " ");
+ for (depmod in uniqmods) {
+ delete uniqmods[depmod];
+ }
+ for (i in depmods) {
+ depmod = depmods[i];
+ # Ignore kernel, as always loaded.
+ if (depmod != "kernel" && depmod != mod)
+ uniqmods[depmod] = 1;
+ }
+ modlist = ""
+ depcount[mod] = 0
+ for (depmod in uniqmods) {
+ modlist = modlist " " depmod;
+ inverse_dependencies[depmod] = inverse_dependencies[depmod] " " mod
+ depcount[mod]++
+ total_depcount++
+ }
+ if (mod == "all_video") {
+ continue;
+ }
+ printf "%s:%s\n", mod, modlist;
+ }
+
+ # Check that we have no dependency circles
+ while (total_depcount != 0) {
+ something_done = 0
+ for (mod in depcount) {
+ if (depcount[mod] == 0) {
+ delete depcount[mod]
+ split(inverse_dependencies[mod], inv_depmods, " ");
+ for (ctr in inv_depmods) {
+ depcount[inv_depmods[ctr]]--
+ total_depcount--
+ }
+ delete inverse_dependencies[mod]
+ something_done = 1
+ }
+ }
+ if (something_done == 0) {
+ for (mod in depcount) {
+ circle = circle " " mod
+ }
+ printf "error: modules %s form a dependency circle\n", circle >"/dev/stderr";
+ exit 1
+ }
+ }
+ modlist = ""
+ while (getline <"video.lst") {
+ modlist = modlist " " $1;
+ }
+ printf "all_video:%s\n", modlist;
+}