summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1997-09-02 15:37:49 (GMT)
committerRobb Matzke <matzke@llnl.gov>1997-09-02 15:37:49 (GMT)
commit07dacb9486230fe2522efca266ab06f4558527c3 (patch)
tree98a034786d7de44863d7d6e247b8b4261ab40d32
parent064648a1f6c43e36da540ca28136b72bd038084e (diff)
downloadhdf5-07dacb9486230fe2522efca266ab06f4558527c3.zip
hdf5-07dacb9486230fe2522efca266ab06f4558527c3.tar.gz
hdf5-07dacb9486230fe2522efca266ab06f4558527c3.tar.bz2
[svn-r60] ./bin/checkposix NEW
Perl script that looks for Posix functions that haven't been protected by adding `HD' to the beginning of the name. It takes a list of .c file names as arguments. ./bin/errors NEW A filter that takes a function prologue and function body as standard input and updates the error list in the prologue based on the function body. You must add the `ERRORS' or `Errors:' field to the prologue before you pass it through this filter or else the errors come out as a separate comment. The errors field must be terminated with a blank line in the prologue so we know where the end is. I may enhance this in the future to take an entire file as standard input instead of individual functions.
-rwxr-xr-xbin/checkposix61
-rwxr-xr-xbin/errors127
2 files changed, 188 insertions, 0 deletions
diff --git a/bin/checkposix b/bin/checkposix
new file mode 100755
index 0000000..aaf9169
--- /dev/null
+++ b/bin/checkposix
@@ -0,0 +1,61 @@
+#!/usr/local/bin/perl -w
+require 5.003;
+
+# Copyright (C) 1997 National Center for Supercomputing Applications.
+# All rights reserved.
+#
+# Robb Matzke, matzke@llnl.gov
+# 30 Aug 1997
+#
+# Purpose: Given the names of C source files this script will print the
+# file name, line number, and function name of any function that
+# doesn't begin with the letter `h' or `H' as stipulated by the
+# HDF5 programming style guide.
+#
+# Emacs users can run this script as the compile command and
+# use `next-error' (usually bound to M-`) to find each name
+# violation.
+
+while (<>) {
+
+ # Get rid of comments by removing the inside part.
+ s|/\*.*?\*/||g;
+ if ($in_comment) {
+ if (/\*\//) {
+ s|.*?\*/||;
+ $in_comment = 0;
+ } else {
+ $_="\n";
+ }
+ } elsif (m|/\*|) {
+ s|/\*.*||;
+ $in_comment = 1;
+ }
+
+ # Get rid of string constants if they begin and end on this line.
+ s/([\'\"])([^\1]|\\\1)*?\1/$1$1/g;
+
+
+ # Now find all function calls on this line
+ while (($name)=/\b([a-gi-z_A-GI-Z]\w*)\s*\(/) {
+ $_ = $';
+
+ # Ignore C statements that look sort of like function
+ # calls.
+ next if $name =~ /^(if|for|return|sizeof|switch|while)$/;
+
+ # These are really HDF5 functions/macros even though they don't
+ # start with `h' or `H'.
+ next if $name =~ /^FUNC_(ENTER|LEAVE)$/;
+ next if $name =~ /^U?INT(8|16|32|64)(ENCODE|DECODE)$/;
+ next if $name =~ /^(MIN|MAX3?|NELMTS|BOUND|CONSTR)$/;
+
+ # These functions/macros are exempt.
+ next if $name =~ /^(assert|main|[fs]?printf)$/;
+
+ print "$ARGV:$.: $name\n";
+ }
+
+} continue {
+ close ARGV if eof;
+}
diff --git a/bin/errors b/bin/errors
new file mode 100755
index 0000000..28585cd
--- /dev/null
+++ b/bin/errors
@@ -0,0 +1,127 @@
+#!/usr/local/bin/perl -w
+require 5.003;
+use Text::Tabs;
+
+# Copyright (C) 1997 National Center for Supercomputing Applications.
+# All rights reserved.
+#
+# Robb Matzke, matzke@llnl.gov
+# 30 Aug 1997
+#
+# Purpose: This script will read standard input which should be a
+# function prologue followed by a C function and will emit
+# on standard output the same source code with the function
+# prologue containing documentation for the various errors
+# that occur in the function.
+#
+# Errors are raised by calling HGOTO_ERROR() or
+# HRETURN_ERROR(). The reason for the error message is a
+# comment which appears immediately after the error macro
+# call and is contained entirely on one line:
+#
+# HRETURN_ERROR (...); /*entry not found*/
+#
+# If such a comment doesn't exist, then the previous comment
+# is used, subject to the constraint that raising an error
+# clears the previous comment.
+#
+# /* Entry not found */
+# HGOTO_ERROR (...);
+#
+# Emacs users can use this script interactively with the
+# c-mark-function and shell-command-on-region functions which
+# are normally bound to M-C-h and M-|.
+
+
+# Split STDIN into the prolog and the function body. Preserve leading
+# white space.
+$_ = join "", <STDIN>;
+my ($head, $prolog, $body) = (/^(\s*)(\/\*(.*?)\*\/)?(.*)/s)[0,2,3];
+$prolog = "" unless $prolog;
+
+# Find each error and the comment that goes with it.
+for ($_=$body,$comment=""; /\/\*|H(RETURN|GOTO)_ERROR/s;) {
+ $_ = $&.$';
+
+ if (/^H(RETURN|GOTO)_ERROR\s*\(\s*H5E_(\w+)\s*,\s*H5E_(\w+)\s*,/s) {
+ ($major, $minor, $_) = ($2, $3, $');
+ $comment=$1 if /^.*?\)\s*;\s*\/\*\s*(.*?)\s*\*\//;
+ $comment =~ s/^\s*\*+\s*/ /mg; # leading asterisks.
+ $comment =~ s/^\s+//s; # leading white space.
+ $comment =~ s/\s+$//s; # trailing white space.
+ $comment =~ s/(\w)$/$1./s; # punctuation.
+ $comment ||= "***NO COMMENT***";
+ $errors{"$major\000$minor\000\u$comment"} = 1;
+ $comment = "";
+
+ } else {
+ ($comment) = /^\/\*\s*(.*?)\s*\*\//s;
+ $_ = $';
+ }
+}
+
+
+# Format an error so it isn't too wide.
+sub fmt_error ($) {
+ local ($_) = @_;
+
+ my ($prefix,$space,$err) = /^((.*?)([A-Z_0-9]+\s+[A-Z_0-9]+\s+))/;
+ $_ = $';
+ tr/\n / /s;
+ my $w = 70 - length expand $prefix;
+ s/(.{$w}\S+)\s+(\S)/$1."\n".$space.' 'x(length $err).$2/eg;
+ return $prefix . $_."\n";
+}
+
+
+
+# Sort the errors by major, then minor, then comment. Duplicate
+# triplets have already been removed.
+sub by_triplet {
+ my ($a_maj, $a_min, $a_com) = split /\000/, $a;
+ my ($b_maj, $b_min, $b_com) = split /\000/, $b;
+ $a_maj cmp $b_maj || $a_min cmp $b_min || $a_com cmp $b_com;
+}
+@errors = map {sprintf "%-9s %-13s %s\n", split /\000/}
+ sort by_triplet keys %errors;
+
+
+
+# Add the list of errors to the prologue depending on the type of
+# prolog.
+if (($front, $back) = $prolog=~/^(.*?Errors:\s*?(?=\n)).*?\n\s*\*\s*\n(.*)/s) {
+ #| * Errors: |#
+ #| * __list_of_error_messages__ (zero or more lines) |#
+ #| * |#
+ print $head, "/*", $front, "\n";
+ map {print fmt_error " *\t\t".$_} @errors;
+ print " *\n", $back, "*/", $body;
+
+} elsif (($front,$back) = $prolog =~
+ /(.*?\n\s*ERRORS:?\s*?(?=\n)).*?\n\s*\n(.*)/s) {
+ #| ERRORS |#
+ #| __list_of_error_messages__ (zero or more lines) |#
+ #| |#
+ print $head, "/*", $front, "\n";
+ map {print fmt_error " ".$_} @errors;
+ print "\n", $back, "*/", $body;
+
+} elsif ($prolog eq "") {
+ # No prolog present.
+ print $head;
+ print " \n/*", "-"x73, "\n * Function:\t\n *\n * Purpose:\t\n *\n";
+ print " * Errors:\n";
+ map {print fmt_error " *\t\t".$_} @errors;
+ print " *\n * Return:\tSuccess:\t\n *\n *\t\tFailure:\t\n *\n";
+ print " * Programmer:\t\n *\n * Modifications:\n *\n *", '-'x73, "\n";
+ print " */\n", $body;
+
+} else {
+ # Prolog format not recognized.
+ print $head, "/*", $prolog, "*/\n\n";
+ print "/*\n * Errors returned by this function...\n";
+ map {print fmt_error " *\t".$_} @errors;
+ print " */\n", $body;
+}
+
+