2 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 # Copyright (C) 2006 Daniel M. Eischen. All rights reserved.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
15 # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # Make a list of all the library versions listed in the master file.
33 # versions[] - array indexed by version name, contains number
34 # of symbols (+ 1) found for each version.
35 # successors[] - array index by version name, contains successor
37 # symbols[][] - array index by [version name, symbol index], contains
38 # names of symbols defined for each version.
39 # names[] - array index is symbol name and value is its first version seen,
40 # used to check for duplicate symbols and warn about them.
47 stderr = "/dev/stderr";
48 while (getline < vfile) {
52 # Strip leading and trailing whitespace.
53 sub("^[ \t]+", "", $0);
54 sub("[ \t]+$", "", $0);
56 if (/^[a-zA-Z0-9._]+[ \t]*{$/) {
62 successors[symver] = "";
63 generated[symver] = 0;
66 else if (/^}[ \t]*[a-zA-Z0-9._]+[ \t]*;$/) {
67 v = $1 != "}" ? $1 : $2;
73 printf("File %s: Unmatched bracket.\n",
77 else if (versions[v] != 1) {
78 printf("File %s: `%s' has unknown " \
80 vfile, symver, v) > stderr;
84 successors[symver] = v;
87 else if (/^}[ \t]*;$/) {
89 printf("File %s: Unmatched bracket.\n",
97 printf("File %s: Missing final semicolon.\n",
102 ; # Ignore blank lines.
104 printf("File %s: Unknown directive: `%s'.\n",
113 # Set meaningful filename for diagnostics.
114 filename = FILENAME != "" ? FILENAME : "<stdin>";
116 # Delete comments, preceding and trailing whitespace, then
117 # consume blank lines.
119 sub("^[ \t]+", "", $0);
120 sub("[ \t]+$", "", $0);
125 /^[a-zA-Z0-9._]+[ \t]*{$/ {
126 # Strip bracket from version name.
128 if (current_version != "") {
129 printf("File %s, line %d: Illegal nesting detected.\n",
130 filename, FNR) > stderr;
133 else if (versions[$1] == 0) {
134 printf("File %s, line %d: Undefined " \
135 "library version `%s'.\n", filename, FNR, $1) > stderr;
137 # Remove this entry from the versions.
141 current_version = $1;
146 /^[a-zA-Z0-9._]+[ \t]*;$/ {
149 if (current_version != "") {
150 count = versions[current_version];
151 versions[current_version]++;
152 symbols[current_version, count] = $1;
153 if ($1 in names && names[$1] != current_version) {
155 # A graver case when a dup symbol appears under
156 # different versions in the map. That can result
157 # in subtle problems with the library later.
159 printf("File %s, line %d: Duplicated symbol `%s' " \
160 "in version `%s', first seen in `%s'. " \
161 "Did you forget to move it to ObsoleteVersions?\n",
163 current_version, names[$1]) > stderr;
166 else if (names[$1] == current_version) {
168 # A harmless case: a dup symbol with the same version.
170 printf("File %s, line %d: warning: " \
171 "Duplicated symbol `%s' in version `%s'.\n",
172 filename, FNR, $1, current_version) > stderr;
176 names[$1] = current_version;
179 printf("File %s, line %d: Symbol `%s' outside version scope.\n",
180 filename, FNR, $1) > stderr;
189 printf("File %s, line %d: Unmatched bracket.\n",
190 filename, FNR, $1) > stderr;
192 brackets = 0; # Reset
194 current_version = "";
200 printf("File %s, line %d: Unknown directive: `%s'.\n",
201 filename, FNR, $0) > stderr;
205 function print_version(v)
207 # This function is recursive, so return if this version
208 # has already been printed. Otherwise, if there is an
209 # ancestral version, recursively print its symbols before
210 # printing the symbols for this version.
212 if (generated[v] == 1)
214 if (successors[v] != "")
215 print_version(successors[v]);
219 # The version count is always one more that actual,
220 # so the loop ranges from 1 to n-1.
222 for (i = 1; i < versions[v]; i++) {
225 printf("\t%s;\n", symbols[v, i]);
229 if (version_count == 0) {
233 if (successors[v] == "")
236 printf("} %s;\n", successors[v]);
244 printf("%d error(s) total.\n", errors) > stderr;
248 for (v in versions) {