summary refs log tree commit diff
path: root/scripts/gen-sorted.awk
blob: 9669277b31f53da703c59c003f925ddbad91670e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/awk -f
# Generate sorted list of directories.  The sorting is stable but with
# dependencies between directories resolved by moving dependees in front.
# Copyright (C) 1998-2016 Free Software Foundation, Inc.
# Written by Ulrich Drepper <drepper@cygnus.com>, 1998.

BEGIN {
  cnt = split(subdirs, all) + 1
  dnt = 0
}

# Let input files have comments.
{ sub(/[ 	]*#.*$/, "") }
NF == 0 { next }

{
  subdir = type = FILENAME;
  sub(/^.*\//, "", type);
  sub(/\/[^/]+$/, "", subdir);
  sub(/^.*\//, "", subdir);
  thisdir = "";
}

type == "Depend" && NF == 1 {
  from[dnt] = subdir;
  to[dnt] = $1;
  ++dnt;
  next
}

type == "Subdirs" && NF == 1 { thisdir = $1 }

type == "Subdirs" && NF == 2 && $1 == "first" {
  thisdir = $2;
  # Make the first dir in the list depend on this one.
  from[dnt] = all[1];
  to[dnt] = thisdir;
  ++dnt;
}

type == "Subdirs" && NF == 2 && $1 == "inhibit" {
  inhibit[$2] = subdir;
  next
}

type == "Subdirs" && thisdir {
  all[cnt++] = thisdir;

  if (FILENAME ~ (srcpfx ? /^\.\.\/sysdeps\// : /^sysdeps\//) \
      || system("test -d " srcpfx thisdir) == 0) {
    # This Subdirs file is in the main source tree,
    # or this subdirectory exists in the main source tree.
    this_srcdir = srcpfx thisdir
  }
  else {
    # The Subdirs file comes from an add-on that should have the subdirectory.
    dir = FILENAME;
    do
      sub(/\/[^/]+$/, "", dir);
    while (dir !~ /\/sysdeps$/);
    sub(/\/sysdeps$/, "", dir);
    if (system("test -d " dir "/" thisdir) == 0)
      dir = dir "/" thisdir;
    else {
      sub(/\/[^/]+$/, "", dir);
      if (system("test -d " dir "/" thisdir) == 0)
        dir = dir "/" thisdir;
      else {
	print FILENAME ":" FNR ":", "cannot find", thisdir > "/dev/stderr";
	exit 2
      }
    }
    file = dir "/Depend";
    if (srcpfx)
      sub(/^\.\.\//, "", dir);
    if (dir !~ /^\/.*$/)
      dir = "$(..)" dir;
    print thisdir "-srcdir", ":=", dir;
  }
  file = this_srcdir "/Depend";
  if (system("test -f " file) == 0) {
    ARGV[ARGC++] = file;
    # Emit a dependency on the implicitly-read file.
    if (srcpfx)
      sub(/^\.\.\//, "", file);
    if (file !~ /^\/.*$/)
      file = "$(..)" file;
    print "$(common-objpfx)sysd-sorted:", "$(wildcard", file ")";
  }
  next
}

{
  print FILENAME ":" FNR ":", "what type of file is this?" > "/dev/stderr";
  exit 2
}

END {
  do {
    moved = 0
    for (i = 0; i < dnt; ++i) {
      for (j = 1; j < cnt; ++j) {
	if (all[j] == from[i]) {
	  for (k = j + 1; k < cnt; ++k) {
	    if (all[k] == to[i]) {
	      break;
	    }
	  }
	  if (k < cnt) {
	    for (l = k - 1; l >= j; --l) {
	      all[l + 1] = all[l]
	    }
	    all[j] = to[i]
	    break;
	  }
	}
      }
      if (j < cnt) {
	moved = 1
	break
      }
    }
  } while (moved);

  # Make sure we list "elf" last.
  saw_elf = 0;
  printf "sorted-subdirs :=";
  for (i = 1; i < cnt; ++i) {
    if (all[i] in inhibit)
      continue;
    if (all[i] == "elf")
      saw_elf = 1;
    else
      printf " %s", all[i];
  }
  printf "%s\n", saw_elf ? " elf" : "";

  print "sysd-sorted-done := t"
}