1# 2# Copyright (C) 2006 Daniel M. Eischen. All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions 6# are met: 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. 12# 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 23# SUCH DAMAGE. 24# 25# $FreeBSD$ 26# 27 28# 29# Make a list of all the library versions listed in the master file. 30# 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 34# version name. 35# symbols[][] - array index by [version name, symbol index], contains 36# names of symbols defined for each version. 37# 38BEGIN { 39 brackets = 0; 40 errors = 0; 41 version_count = 0; 42 current_version = ""; 43 stderr = "/dev/stderr"; 44 while (getline < vfile) { 45 # Strip comments. 46 sub("#.*$", "", $0); 47 48 # Strip trailing spaces. 49 sub(" *$", "", $0); 50 51 if (/^[ \t]*[a-zA-Z0-9._]+ *{/) { 52 brackets++; 53 symver = $1; 54 versions[symver] = 1; 55 successors[symver] = ""; 56 version_count++; 57 } 58 else if (/^[ \t]*} *[a-zA-Z0-9._]+ *;/) { 59 # Strip semicolon. 60 gsub(";", "", $2); 61 if (symver == "") 62 printf("Unmatched bracket.\n"); 63 else if (versions[$2] != 1) 64 printf("File %s: %s has unknown " \ 65 "successor %s\n", vfile, symver, $2); 66 else 67 successors[symver] = $2; 68 brackets--; 69 } 70 else if (/^[ \t]*};/) { 71 if (symver == "") 72 printf("File %s: Unmatched bracket.\n", 73 vfile) > stderr; 74 # No successor 75 brackets--; 76 } 77 else if (/^[ \t]*}/) { 78 printf("File %s: Missing ending semi-colon.\n", 79 vfile) > stderr; 80 } 81 else if (/^$/) 82 ; # Ignore blank lines. 83 else 84 printf("File %s: Unknown directive: %s\n", 85 vfile, $0) > stderr; 86 } 87 brackets = 0; 88} 89 90/.*/ { 91 # Delete comments, preceding and trailing whitespace, then 92 # consume blank lines. 93 sub("#.*$", "", $0); 94 sub("^[ \t]+", "", $0); 95 sub("[ \t]+$", "", $0); 96 if ($0 == "") 97 next; 98} 99 100/^[a-zA-Z0-9._]+ +{$/ { 101 # Strip bracket from version name. 102 sub("{", "", $1); 103 if (current_version != "") 104 printf("File %s, line %d: Illegal nesting detected.\n", 105 FILENAME, FNR) > stderr; 106 else if (versions[$1] == 0) { 107 printf("File %s, line %d: Undefined " \ 108 "library version %s\n", FILENAME, FNR, $1) > stderr; 109 # Remove this entry from the versions. 110 delete versions[$1]; 111 } 112 else 113 current_version = $1; 114 brackets++; 115 next; 116} 117 118/^[a-zA-Z0-9._]+ *;$/ { 119 if (current_version != "") { 120 count = versions[current_version]; 121 versions[current_version]++; 122 symbols[current_version, count] = $1; 123 } 124 next; 125} 126 127/^} *;$/ { 128 brackets--; 129 if (brackets < 0) { 130 printf("File %s, line %d: Unmatched bracket.\n", 131 FILENAME, FNR, $1) > stderr; 132 brackets = 0; # Reset 133 } 134 current_version = ""; 135 next; 136} 137 138 139/.*/ { 140 printf("File %s, line %d: Unknown directive: '%s'\n", 141 FILENAME, FNR, $0) > stderr; 142} 143 144END { 145 for (v in versions) { 146 printf("\n"); 147 printf("%s {\n", v); 148 149 # The version count is always one more that actual, 150 # so the loop ranges from 1 to n-1. 151 # 152 for (i = 1; i < versions[v]; i++) { 153 if (i == 1) 154 printf("global:\n"); 155 printf("\t%s\n", symbols[v, i]); 156 } 157 if (successors[v] == "") { 158 # This version succeeds no other version. 159 printf("local:\n"); 160 printf("\t*;\n"); 161 printf("};\n"); 162 } 163 else 164 printf("} %s;\n", successors[v]); 165 } 166} 167