[13513] | 1 | function die(msg) { |
---|
| 2 | print msg > "/dev/fd/2"; |
---|
| 3 | # awk will still do the END block before exiting... |
---|
| 4 | justexit = 1; |
---|
| 5 | exit(1); |
---|
| 6 | } |
---|
| 7 | |
---|
| 8 | # Ignore blank lines and comments. |
---|
| 9 | /^ *$/ { next; } |
---|
| 10 | /^#/ { next; } |
---|
| 11 | |
---|
| 12 | # Process normal lines. |
---|
| 13 | { |
---|
| 14 | packages[$1] = 1; |
---|
| 15 | n = 2; |
---|
[14375] | 16 | |
---|
[13513] | 17 | nparts = split($1, parts, /\//); |
---|
| 18 | if (expand[parts[nparts]]) |
---|
| 19 | expand[parts[nparts]] = "AMBIGUOUS"; |
---|
| 20 | else |
---|
| 21 | expand[parts[nparts]] = $1; |
---|
| 22 | expand[$1] = $1; |
---|
| 23 | |
---|
[14375] | 24 | package_names[$1] = "athena-"parts[nparts]; |
---|
| 25 | |
---|
[13513] | 26 | while (n <= NF) { |
---|
| 27 | if ($n == "early") |
---|
| 28 | early[numearly++] = $1; |
---|
| 29 | else if ($n == "late") |
---|
| 30 | late[numlate++] = $1; |
---|
| 31 | else if ($n == "requires") |
---|
| 32 | prereqs[$1] = $++n; |
---|
| 33 | else if ($n == "on" || $n == "except") { |
---|
| 34 | built[$1] = $n == "on"; |
---|
| 35 | split($(n+1), oses, /,/); |
---|
| 36 | for (ind in oses) { |
---|
| 37 | if (os == oses[ind]) |
---|
| 38 | built[$1] = $n == "except"; |
---|
| 39 | } |
---|
| 40 | n++; |
---|
[14375] | 41 | } else if ($n == "package") |
---|
| 42 | package_names[$1] = "athena-"$++n; |
---|
| 43 | else |
---|
[13513] | 44 | die("Bad packages line: " $0); |
---|
| 45 | n++; |
---|
| 46 | } |
---|
| 47 | } |
---|
| 48 | |
---|
| 49 | # Output a package name, preceded by all of its dependencies that haven't |
---|
| 50 | # already been output. |
---|
| 51 | function build(pkg) { |
---|
| 52 | if (built[pkg]) |
---|
| 53 | return; |
---|
| 54 | |
---|
| 55 | if (building[pkg]) |
---|
| 56 | die("Dependency loop for " pkg); |
---|
| 57 | building[pkg] = 1; |
---|
| 58 | |
---|
| 59 | while (prereqs[pkg]) { |
---|
| 60 | # We have to keep re-splitting prereqs because we don't have |
---|
| 61 | # local variables, so if we tried to keep more state the |
---|
| 62 | # recursive calls would write over it. |
---|
| 63 | comma = index(prereqs[pkg], ","); |
---|
| 64 | if (comma) { |
---|
| 65 | req = substr(prereqs[pkg], 0, comma - 1); |
---|
| 66 | prereqs[pkg] = substr(prereqs[pkg], comma + 1); |
---|
| 67 | } else { |
---|
| 68 | req = prereqs[pkg]; |
---|
| 69 | delete prereqs[pkg]; |
---|
| 70 | } |
---|
| 71 | build(expand[req]); |
---|
| 72 | } |
---|
| 73 | |
---|
| 74 | if (start == pkg) |
---|
| 75 | start = ""; |
---|
| 76 | |
---|
| 77 | # If we're not still waiting to see the start package, output name. |
---|
[14375] | 78 | if (!start) { |
---|
| 79 | if (pkgnames) |
---|
| 80 | print pkg " " package_names[pkg] |
---|
| 81 | else |
---|
[13513] | 82 | print pkg; |
---|
[14375] | 83 | } |
---|
[13513] | 84 | |
---|
| 85 | # If that was the end package, we're done. |
---|
| 86 | if (end == pkg) |
---|
| 87 | exit(0); |
---|
| 88 | |
---|
| 89 | built[pkg] = 1; |
---|
| 90 | building[pkg] = 0; |
---|
| 91 | } |
---|
| 92 | |
---|
| 93 | # At the end of the file, output the list of packages to build. |
---|
| 94 | END { |
---|
| 95 | # ...unless we're erroring out. |
---|
| 96 | if (justexit) |
---|
| 97 | exit; |
---|
| 98 | |
---|
| 99 | # Check dependencies. |
---|
| 100 | for (pkg in packages) { |
---|
| 101 | if (!prereqs[pkg]) |
---|
| 102 | continue; |
---|
| 103 | split(prereqs[pkg], reqs, /,/); |
---|
| 104 | for (ind in reqs) { |
---|
| 105 | if (expand[reqs[ind]] == "AMBIGUOUS") |
---|
| 106 | die("Ambiguous package name " reqs[ind]); |
---|
| 107 | else if (!(expand[reqs[ind]] in packages)) |
---|
| 108 | die("No such package " reqs[ind]); |
---|
| 109 | } |
---|
| 110 | } |
---|
| 111 | |
---|
| 112 | # Now remove the late packages from the packages list to keep |
---|
| 113 | # them from being built too soon. |
---|
| 114 | for (i = 0; i < numlate; i++) |
---|
| 115 | delete packages[late[i]]; |
---|
| 116 | |
---|
| 117 | |
---|
| 118 | # Do early packages, in order. |
---|
| 119 | for (i = 0; i < numearly; i++) |
---|
| 120 | build(early[i]); |
---|
| 121 | |
---|
| 122 | # Do normal packages. |
---|
| 123 | for (pkg in packages) |
---|
| 124 | build(pkg); |
---|
| 125 | |
---|
| 126 | # Do late packages, in order. |
---|
| 127 | for (i = 0; i < numlate; i++) |
---|
| 128 | build(late[i]); |
---|
| 129 | } |
---|