]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/mk/version_gen.awk
bsddialog: import version 1.0
[FreeBSD/FreeBSD.git] / share / mk / version_gen.awk
1 #
2 # SPDX-License-Identifier: BSD-2-Clause
3 #
4 # Copyright (C) 2006 Daniel M. Eischen.  All rights reserved.
5
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
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.
14
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
25 # SUCH DAMAGE.
26 #
27 #
28
29 #
30 # Make a list of all the library versions listed in the master file.
31 #
32 #   versions[] - array indexed by version name, contains number
33 #                of symbols (+ 1) found for each version.
34 #   successors[] - array index by version name, contains successor
35 #                  version name.
36 #   symbols[][] - array index by [version name, symbol index], contains
37 #                 names of symbols defined for each version.
38 #   names[] - array index is symbol name and value is its first version seen,
39 #             used to check for duplicate symbols and warn about them.
40 #
41 BEGIN {
42         brackets = 0;
43         errors = warns = 0;
44         version_count = 0;
45         current_version = "";
46         stderr = "/dev/stderr";
47         while (getline < vfile) {
48                 # Strip comments.
49                 sub("#.*$", "", $0);
50
51                 # Strip leading and trailing whitespace.
52                 sub("^[ \t]+", "", $0);
53                 sub("[ \t]+$", "", $0);
54
55                 if (/^[a-zA-Z0-9._]+[ \t]*{$/) {
56                         # Strip brace.
57                         sub("{", "", $1);
58                         brackets++;
59                         symver = $1;
60                         versions[symver] = 1;
61                         successors[symver] = "";
62                         generated[symver] = 0;
63                         version_count++;
64                 }
65                 else if (/^}[ \t]*[a-zA-Z0-9._]+[ \t]*;$/) {
66                         v = $1 != "}" ? $1 : $2;
67                         # Strip brace.
68                         sub("}", "", v);
69                         # Strip semicolon.
70                         sub(";", "", v);
71                         if (symver == "") {
72                                 printf("File %s: Unmatched bracket.\n",
73                                 vfile) > stderr;
74                                 errors++;
75                         }
76                         else if (versions[v] != 1) {
77                                 printf("File %s: `%s' has unknown " \
78                                     "successor `%s'.\n",
79                                     vfile, symver, v) > stderr;
80                                 errors++;
81                         }
82                         else
83                                 successors[symver] = v;
84                         brackets--;
85                 }
86                 else if (/^}[ \t]*;$/) {
87                         if (symver == "") {
88                                 printf("File %s: Unmatched bracket.\n",
89                                     vfile) > stderr;
90                                 errors++;
91                         }
92                         # No successor
93                         brackets--;
94                 }
95                 else if (/^}$/) {
96                         printf("File %s: Missing final semicolon.\n",
97                             vfile) > stderr;
98                         errors++;
99                 }
100                 else if (/^$/)
101                         ;  # Ignore blank lines.
102                 else {
103                         printf("File %s: Unknown directive: `%s'.\n",
104                             vfile, $0) > stderr;
105                         errors++;
106                 }
107         }
108         brackets = 0;
109 }
110
111 {
112         # Set meaningful filename for diagnostics.
113         filename = FILENAME != "" ? FILENAME : "<stdin>";
114
115         # Delete comments, preceding and trailing whitespace, then
116         # consume blank lines.
117         sub("#.*$", "", $0);
118         sub("^[ \t]+", "", $0);
119         sub("[ \t]+$", "", $0);
120         if ($0 == "")
121                 next;
122 }
123
124 /^[a-zA-Z0-9._]+[ \t]*{$/ {
125         # Strip bracket from version name.
126         sub("{", "", $1);
127         if (current_version != "") {
128                 printf("File %s, line %d: Illegal nesting detected.\n",
129                     filename, FNR) > stderr;
130                 errors++;
131         }
132         else if (versions[$1] == 0) {
133                 printf("File %s, line %d: Undefined " \
134                     "library version `%s'.\n", filename, FNR, $1) > stderr;
135                 errors++;
136                 # Remove this entry from the versions.
137                 delete versions[$1];
138         }
139         else
140                 current_version = $1;
141         brackets++;
142         next;
143 }
144
145 /^[a-zA-Z0-9._]+[ \t]*;$/ {
146         # Strip semicolon.
147         sub(";", "", $1);
148         if (current_version != "") {
149                 count = versions[current_version];
150                 versions[current_version]++;
151                 symbols[current_version, count] = $1;
152                 if ($1 in names && names[$1] != current_version) {
153                         #
154                         # A graver case when a dup symbol appears under
155                         # different versions in the map.  That can result
156                         # in subtle problems with the library later.
157                         #
158                         printf("File %s, line %d: Duplicated symbol `%s' " \
159                             "in version `%s', first seen in `%s'. " \
160                             "Did you forget to move it to ObsoleteVersions?\n",
161                             filename, FNR, $1,
162                             current_version, names[$1]) > stderr;
163                         errors++;
164                 }
165                 else if (names[$1] == current_version) {
166                         #
167                         # A harmless case: a dup symbol with the same version.
168                         #
169                         printf("File %s, line %d: warning: " \
170                             "Duplicated symbol `%s' in version `%s'.\n",
171                             filename, FNR, $1, current_version) > stderr;
172                         warns++;
173                 }
174                 else
175                         names[$1] = current_version;
176         }
177         else {
178                 printf("File %s, line %d: Symbol `%s' outside version scope.\n",
179                     filename, FNR, $1) > stderr;
180                 errors++;
181         }
182         next;
183 }
184
185 /^}[ \t]*;$/ {
186         brackets--;
187         if (brackets < 0) {
188                 printf("File %s, line %d: Unmatched bracket.\n",
189                     filename, FNR, $1) > stderr;
190                 errors++;
191                 brackets = 0;   # Reset
192         }
193         current_version = "";
194         next;
195 }
196
197
198 {
199         printf("File %s, line %d: Unknown directive: `%s'.\n",
200             filename, FNR, $0) > stderr;
201         errors++;
202 }
203
204 function print_version(v)
205 {
206         # This function is recursive, so return if this version
207         # has already been printed.  Otherwise, if there is an
208         # ancestral version, recursively print its symbols before
209         # printing the symbols for this version.
210         #
211         if (generated[v] == 1)
212                 return;
213         if (successors[v] != "")
214                 print_version(successors[v]);
215
216         printf("%s {\n", v);
217
218         # The version count is always one more that actual,
219         # so the loop ranges from 1 to n-1.
220         #
221         for (i = 1; i < versions[v]; i++) {
222                 if (i == 1)
223                         printf("global:\n");
224                 printf("\t%s;\n", symbols[v, i]);
225         }
226
227         version_count--;
228         if (version_count == 0) {
229                 printf("local:\n");
230                 printf("\t*;\n");
231         }
232         if (successors[v] == "")
233                 printf("};\n");
234         else
235                 printf("} %s;\n", successors[v]);
236         printf("\n");
237
238         generated[v] = 1;
239     }
240
241 END {
242         if (errors) {
243                 printf("%d error(s) total.\n", errors) > stderr;
244                 exit(1);
245         }
246         # OK, no errors.
247         for (v in versions) {
248                 print_version(v);
249         }
250 }