2 # Copyright (C) 2006 Daniel M. Eischen. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
7 # 1. Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # 2. Redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution.
13 # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 # Make a list of all the library versions listed in the master file.
31 # versions[] - array indexed by version name, contains number
32 # of symbols (+ 1) found for each version.
33 # successors[] - array index by version name, contains successor
35 # symbols[][] - array index by [version name, symbol index], contains
36 # names of symbols defined for each version.
37 # names[] - array index is symbol name and value is its first version seen,
38 # used to check for duplicate symbols and warn about them.
45 stderr =
"/dev/stderr";
46 while (getline < vfile
) {
50 # Strip leading and trailing whitespace.
51 sub("^[ \t]+", "", $
0);
52 sub("[ \t]+$", "", $
0);
54 if (/^
[a
-zA
-Z0
-9._
]+[ \t]*{$
/) {
60 successors
[symver
] =
"";
61 generated
[symver
] =
0;
64 else if (/^
}[ \t]*[a
-zA
-Z0
-9._
]+[ \t]*;$
/) {
65 v = $
1 != "}" ? $
1 : $
2;
71 printf("File %s: Unmatched bracket.\n",
75 else if (versions
[v
] != 1) {
76 printf("File %s: `%s' has unknown " \
78 vfile
, symver
, v
) > stderr
;
82 successors
[symver
] = v
;
85 else if (/^
}[ \t]*;$
/) {
87 printf("File %s: Unmatched bracket.\n",
95 printf("File %s: Missing final semicolon.\n",
100 ; # Ignore blank lines.
102 printf("File %s: Unknown directive: `%s'.\n",
111 # Set meaningful filename for diagnostics.
112 filename =
FILENAME != "" ?
FILENAME : "<stdin>";
114 # Delete comments, preceding and trailing whitespace, then
115 # consume blank lines.
117 sub("^[ \t]+", "", $
0);
118 sub("[ \t]+$", "", $
0);
123 /^
[a
-zA
-Z0
-9._
]+[ \t]*{$
/ {
124 # Strip bracket from version name.
126 if (current_version
!= "") {
127 printf("File %s, line %d: Illegal nesting detected.\n",
128 filename, FNR) > stderr
;
131 else if (versions
[$
1] ==
0) {
132 printf("File %s, line %d: Undefined " \
133 "library version `%s'.\n", filename, FNR, $
1) > stderr
;
135 # Remove this entry from the versions.
139 current_version = $
1;
144 /^
[a
-zA
-Z0
-9._
]+[ \t]*;$
/ {
147 if (current_version
!= "") {
148 count = versions
[current_version
];
149 versions
[current_version
]++;
150 symbols
[current_version
, count
] = $
1;
151 if ($
1 in names
&& names
[$
1] != current_version
) {
153 # A graver case when a dup symbol appears under
154 # different versions in the map. That can result
155 # in subtle problems with the library later.
157 printf("File %s, line %d: Duplicated symbol `%s' " \
158 "in version `%s', first seen in `%s'. " \
159 "Did you forget to move it to ObsoleteVersions?\n",
161 current_version
, names
[$
1]) > stderr
;
164 else if (names
[$
1] == current_version
) {
166 # A harmless case: a dup symbol with the same version.
168 printf("File %s, line %d: warning: " \
169 "Duplicated symbol `%s' in version `%s'.\n",
170 filename, FNR, $
1, current_version
) > stderr
;
174 names
[$
1] = current_version
;
177 printf("File %s, line %d: Symbol `%s' outside version scope.\n",
178 filename, FNR, $
1) > stderr
;
187 printf("File %s, line %d: Unmatched bracket.\n",
188 filename, FNR, $
1) > stderr
;
190 brackets =
0; # Reset
192 current_version =
"";
198 printf("File %s, line %d: Unknown directive: `%s'.\n",
199 filename, FNR, $
0) > stderr
;
203 function print_version
(v
)
205 # This function is recursive, so return if this version
206 # has already been printed. Otherwise, if there is an
207 # ancestral version, recursively print its symbols before
208 # printing the symbols for this version.
210 if (generated
[v
] ==
1)
212 if (successors
[v
] != "")
213 print_version
(successors
[v
]);
217 # The version count is always one more that actual,
218 # so the loop ranges from 1 to n-1.
220 for (i =
1; i
< versions
[v
]; i
++) {
223 printf("\t%s;\n", symbols
[v
, i
]);
227 if (version_count ==
0) {
231 if (successors
[v
] ==
"")
234 printf("} %s;\n", successors
[v
]);
242 printf("%d error(s) total.\n", errors
) > stderr
;
246 for (v in versions
) {