From f015ed90ef10b6441ebea1eeea6b674292b2a409 Mon Sep 17 00:00:00 2001 From: deischen Date: Thu, 16 Mar 2006 15:12:26 +0000 Subject: Teach bsd.lib.mk to auto generate a version map file based on a set of symbol definitions (VERSION_DEF) and symbol mappings (SYMBOL_MAPS). Add an awk script to generate the version map. Suggested by: ru Helped by: ru Reviewed by: ru --- share/mk/version_gen.awk | 166 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 share/mk/version_gen.awk (limited to 'share/mk/version_gen.awk') diff --git a/share/mk/version_gen.awk b/share/mk/version_gen.awk new file mode 100644 index 0000000..23c502c --- /dev/null +++ b/share/mk/version_gen.awk @@ -0,0 +1,166 @@ +# +# Copyright (C) 2006 Daniel M. Eischen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +# +# Make a list of all the library versions listed in the master file. +# +# versions[] - array indexed by version name, contains number +# of symbols (+ 1) found for each version. +# successors[] - array index by version name, contains successor +# version name. +# symbols[][] - array index by [version name, symbol index], contains +# names of symbols defined for each version. +# +BEGIN { + brackets = 0; + errors = 0; + version_count = 0; + current_version = ""; + stderr = "/dev/stderr"; + while (getline < vfile) { + # Strip comments. + sub("#.*$", "", $0); + + # Strip trailing spaces. + sub(" *$", "", $0); + + if (/^[ \t]*[a-zA-Z0-9._]+ *{/) { + brackets++; + symver = $1; + versions[symver] = 1; + successors[symver] = ""; + version_count++; + } + else if (/^[ \t]*} *[a-zA-Z0-9._]+ *;/) { + # Strip semicolon. + gsub(";", "", $2); + if (symver == "") + printf("Unmatched bracket.\n"); + else if (versions[$2] != 1) + printf("File %s: %s has unknown " \ + "successor %s\n", vfile, symver, $2); + else + successors[symver] = $2; + brackets--; + } + else if (/^[ \t]*};/) { + if (symver == "") + printf("File %s: Unmatched bracket.\n", + vfile) > stderr; + # No successor + brackets--; + } + else if (/^[ \t]*}/) { + printf("File %s: Missing ending semi-colon.\n", + vfile) > stderr; + } + else if (/^$/) + ; # Ignore blank lines. + else + printf("File %s: Unknown directive: %s\n", + vfile, $0) > stderr; + } + brackets = 0; +} + +/.*/ { + # Delete comments, preceding and trailing whitespace, then + # consume blank lines. + sub("#.*$", "", $0); + sub("^[ \t]+", "", $0); + sub("[ \t]+$", "", $0); + if ($0 == "") + next; +} + +/^[a-zA-Z0-9._]+ +{$/ { + # Strip bracket from version name. + sub("{", "", $1); + if (current_version != "") + printf("File %s, line %d: Illegal nesting detected.\n", + FILENAME, FNR) > stderr; + else if (versions[$1] == 0) { + printf("File %s, line %d: Undefined " \ + "library version %s\n", FILENAME, FNR, $1) > stderr; + # Remove this entry from the versions. + delete versions[$1]; + } + else + current_version = $1; + brackets++; + next; +} + +/^[a-zA-Z0-9._]+ *;$/ { + if (current_version != "") { + count = versions[current_version]; + versions[current_version]++; + symbols[current_version, count] = $1; + } + next; +} + +/^} *;$/ { + brackets--; + if (brackets < 0) { + printf("File %s, line %d: Unmatched bracket.\n", + FILENAME, FNR, $1) > stderr; + brackets = 0; # Reset + } + current_version = ""; + next; +} + + +/.*/ { + printf("File %s, line %d: Unknown directive: '%s'\n", + FILENAME, FNR, $0) > stderr; +} + +END { + for (v in versions) { + printf("\n"); + printf("%s {\n", v); + + # The version count is always one more that actual, + # so the loop ranges from 1 to n-1. + # + for (i = 1; i < versions[v]; i++) { + if (i == 1) + printf("global:\n"); + printf("\t%s\n", symbols[v, i]); + } + if (successors[v] == "") { + # This version succeeds no other version. + printf("local:\n"); + printf("\t*;\n"); + printf("};\n"); + } + else + printf("} %s;\n", successors[v]); + } +} -- cgit v1.1