diff options
Diffstat (limited to 'manual/summary-check.awk')
-rw-r--r-- | manual/summary-check.awk | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/manual/summary-check.awk b/manual/summary-check.awk new file mode 100644 index 0000000..b3e447f --- /dev/null +++ b/manual/summary-check.awk @@ -0,0 +1,139 @@ +# awk script to create a C file from summary.texinfo +# Copyright (C) 2013 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +# This script groks the summary.texi (summary.awk output) format. +# It produces a compilable C file attempts to refer to each declaration +# in summary.texi so as to verify that the types in the manual match the +# types in the code. + +BEGIN { + wraps["@w{"] = 1; + wraps["@t{"] = 1; + wraps["@emph{"] = 1; + + print "/* This file is generated by summary-check.awk; DO NOT EDIT! */"; + print ""; +} + +NF == 2 && $1 == "@comment" { + ident = $2; + optional = 0; + next +} +NF == 3 && $1 == "@comment" && $3 = "(optional)" { + ident = $2; + optional = 1; + next +} +NF >= 4 && $1 == "@c" { + source = $2; + lineno = $3; + flavor = $4; + for (i = 5; i <= NF; ++i) + flavor = flavor " " $i; + next +} +$1 == "@item" { + $1 = ""; + gsub(/@var{[^}]+}/, ""); + gsub(/@dots{}/, "..."); + gsub(/@\*/, " "); + decl = $0 ";"; + for (wrap in wraps) { + len = length(wrap); + while ((first = match(decl, wrap)) > 0) { + depth = 1; + for (i = first + len; i < length(decl); ++i) { + c = substr(decl, i, 1); + if (c == "{") ++depth; + else if (c == "}" && --depth == 0) { + left = substr(decl, 1, first - 1); + middle = substr(decl, first + len, i - (first + len)); + right = substr(decl, i + 1); + decl = left middle right; + break; + } + } + } + } + sub(/\.\.\.,.+);/, "...);", decl); # execle + sub(/\[,[^],]+\]/, ", ...", decl); # open + next +} + +/^@file{/ { + gsub(/[^a-zA-Z0-9_]/, "", ident); + undef = 1; + if (flavor ~ /@defvrx?/) { + # These are used for feature-test macros. There is nothing we can test. + next; + } + if (flavor ~ /@itemx?/ || flavor == "@vindex") { + # These are used for macros, but we have no type information. + next; + } + if (flavor == "@defvar") { + # These are used for variables, but we have no type information. + next; + } + if (flavor == "@defmac") { + # These are used for function-like macros, but we have no type information. + next; + } + if (flavor ~ /^@deftypevrx? {Data type}$/ || flavor == "@deftp") { + # This is a type. We can just test that it's usable. + decl = "extern " ident " test_" ident ";"; + } + else if (flavor ~ /^@deftypevrx?/) { + # These are used for macros. + sub(ident, "test_" ident " (void) { return " ident "; }", decl); + undef = 0 + } + + if (decl ~ /float-type/ || decl ~ /real-floating/) { + # Special case: these are function-like macros that + # cannot be redeclared. There isn't a simple way to test. + next + } + + if (ident in seen) + next; + seen[ident] = 1 + + gsub(/,/, ""); + for (i = 1; i <= NF && $i ~ /@file{[^}]+}/; ++i) { + header = gensub(/@file{([^}]+)}/, "\\1", 1, $i); + print "#include", "<" header ">"; + } + if (optional) + print "#ifdef", ident; + else if (undef) + print "#undef", ident; + print "#", lineno, "\"" source "\""; + print decl; + if (optional) + print "#endif", "/*", ident, "*/"; +} + +END { + print ""; + print "int main (void)"; + print "{"; + print " return 0;"; + print "}"; +} |