home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume42
/
ccount
/
part03
< prev
next >
Wrap
Internet Message Format
|
1994-03-29
|
46KB
From: prechelt@ira.uka.de (Lutz Prechelt)
Newsgroups: comp.sources.misc
Subject: v42i022: ccount - syntactic readability analysis tool, Part03/03
Date: 29 Mar 1994 20:37:22 -0600
Organization: Sterling Software
Sender: kent@sparky.sterling.com
Approved: kent@sparky.sterling.com
Message-ID: <2naol2$ga3@sparky.sterling.com>
X-Md4-Signature: f6083da242a7b94b956b86f80ac8be13
Submitted-by: prechelt@ira.uka.de (Lutz Prechelt)
Posting-number: Volume 42, Issue 22
Archive-name: ccount/part03
Environment: Perl, sh
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: Ccount/README.2 Ccount/statty Ccount/stattyB
# Ccount/stattyCSE Ccount/stattyF Ccount/stattyM
# Wrapped by kent@sparky on Thu Mar 24 20:42:23 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 3 (of 3)."'
if test -f 'Ccount/README.2' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Ccount/README.2'\"
else
echo shar: Extracting \"'Ccount/README.2'\" \(8697 characters\)
sed "s/^X//" >'Ccount/README.2' <<'END_OF_FILE'
X*****************************************************************************
X
X R E A D M E FILE of STATISTICAL T O O L S
X
X*****************************************************************************
X
XAuthor: Joerg Lawrenz, Universitaet Karlsruhe
XDate: 93/12/1
X
X
X=============================================================================
X1. Tools for statistical analysis of 'ccount' outputs
X=============================================================================
X
XThe following PERL programs read data files in 'ccount' output format and
Xgive statistical reports about modules, functions, blocks, control structures
Xand expressions of C source files:
X
X stattyM --> module report
X stattyF --> function report
X stattyCSE --> control structures & expression report
X stattyB --> block report
X statty --> all reports
X
XNote: Before using these tools you possibly have to change the PERL path
Xin the first line of each tool script.
X
X
XAll the reports have the format of a table and they only differ from each
Xother in the values and in the first column where are, one per line, the
Xattributes (e.g. nesting depth) of an object (e.g. if-statement).
XTo the right of each attribute you find 17 values:
X
X 1. average
X 2. standard deviation
X 3. maximum
X 4. 25%-quantile
X 5. exact percentage of the above
X 6. 50%-quantile
X 7. exact percentage of the above
X 8. 75%-quantile
X 9. exact percentage of the above
X 10. 90%-quantile
X 11. exact percentage of the above
X 12. 95%-quantile
X 13. exact percentage of the above
X 14. 98%-quantile
X 15. exact percentage of the above
X 16. 99%-quantile
X 17. exact percentage of the above
X
XBecause of discrete values, quantiles can only be approximated. Therefore a
Xx%-quantile here is that attribute value (starting by zero) by which the
Xaccumulated frequency (in percent) of an object is equal or just greater
Xthan x%. In order to estimate deviations, the exact percentage is indicated
Xfor each quantile.
XLet us assume for example that in the module report the 50%-quantile (median)
Xof the number of functions is 2 and the exact according percentage is 54.4%.
XThat means that 54.4% of all modules have one or two functions, and less
Xthan half the modules have one function.
X
XIn the first line of each report there is indicated the path from which the
Xtool producing the according report was started. You will find also the name
Xof the first and the last '*.out'-file of all files that were regarded.
X
XAll reports are 143 columns wide.
X
X=============================================================================
X2. Further details about the individual reports
X=============================================================================
X
XSee also 'README.1', section 4: output format of 'ccount' program.
X(-> nesting depth, operators and block length)
X
XThe numbers of the objects examined by the respective tool are added at the
Xend of the report.
X
X
XI. MODULE REPORT
X-----------------
X
X Usage: stattyM report-filename [ + exclude-files - ] input-files
X
X You can exclude certain files from byte and line count statistics
X by enclosing their names in '+' and '-'. The affected
X attributes are marked with '~' below.
X The number of the excluded files is added at the end of the report.
X Note that you have to list the excluded files as normal input
X files again in the last part of the command line.
X
X The following module attributes are considered:
X
X 1. Length (in bytes) ~
X 2. Length (in lines) ~
X 3. Average line length (in bytes) ~
X
X 4. Comments (in bytes) ~
X 5. Preprocessor comments (in bytes) ~
X (see 'README.1', 2.2)
X 6. Bytes of relevant symbols and words ~
X (i.e. identifier, symbols, keywords and
X preprocessor directives)
X 7. Bytes of 'blanks' ~
X (i.e. blanks, carriage returns, tabs ...)
X
X 8. Portion of comment (in percent) ~
X 9. Portion of preprocessor comment (in percent) ~
X 10. Portion of relevant symbols and words (in percent) ~
X 11. Portion of 'blanks' (in percent) ~
X
X 12. Number of identifier uses
X 13. Total accumulated length of identifier uses (in bytes)
X
X 14. Number of keyword or symbol uses
X 15. Total accumulated length of keyword/symbol uses (in bytes)
X
X 16. Number of preprocessor directives
X 17. Total accumulated length of preproc. directives (in bytes)
X
X 18. Total number of ';'
X 19. Number of functions
X
X 20. Average innermost block length (in semicolons)
X 21. Standard deviation of the above
X 22. Maximum innermost block length (in semicolons)
X
X 23. Average average block nesting depth per function
X 24. Standard deviation of the above
X 25. Maximum average block nesting depth per function
X
X
X
XII. FUNCTION REPORT
X--------------------
X
X Usage: stattyF report-filename [ + exclude-files - ] input-files
X
X See I. for the handling of 'exclude-files'!
X
X The following function attributes are considered:
X
X 1. Length (in bytes) ~
X 2. Length (in lines) ~
X 3. Average line length (in bytes) ~
X
X 4. Comments (in bytes) ~
X 5. Portion of comment (in percent) ~
X
X 6. Number of 'if' statements
X 7. Number of 'while' or 'do' statements
X 8. Number of 'for' statements
X 9. Number of 'switch' statements
X 10. Number of 'goto' statements
X 11. Number of labels
X
X 12. Number of ';'
X 13. Number of all blocks
X
X 14. Average innermost block length (in semicolons)
X 15. Standard deviation of the above
X 16. Maximum innermost block length in (in semicolons)
X
X 17. Average block nesting depth
X 18. Standard deviation of the above
X 19. Maximum block nesting depth
X
X
X
XIII. CONTROL STRUCTURES & EXPRESSION REPORT
X---------------------------------------------
X
X Usage: stattyCSE report-filename input-files
X
X The following attributes are considered:
X
X 'if' statement:
X 1. Length total (in lines)
X 2. Number of ';' total
X 3. Length of 'then' part (in lines)
X 4. Number of ';' in 'then' part
X 5. Length of 'else' part (in lines)
X 6. Number of ';' in 'else' part
X 7. Nesting depth
X 8. Number of operators in 'if' condition
X
X 'while' or 'do' statement:
X 9. Length total (in lines)
X 10. Number of ';'
X 11. Number of 'break' or 'continue' statements
X regarding this 'do' or 'while'
X 12. Nesting depth
X 13. Number of operators in 'while' condition
X
X 'for' statement:
X 14. Length total (in lines)
X 15. Number of ';' (including those in head)
X 16. Number of break statements regarding this 'for'
X 17. Nesting depth
X 18. Number of operators in second expression of head
X
X 'switch' statement:
X 19. Length total (in lines)
X 20. Number of ';'
X 21. Number of case labels
X 22. Number of break statements regarding this 'switch'
X 23. Nesting depth
X 24. Number of operators in head expression
X
X expression statement (i.e. expression followed by ';'):
X 25. Nesting depth
X 26. Number of operators
X
X
X
XIV. BLOCK REPORT
X-----------------
X
X Usage: stattyB report-filename input-files
X
X The following attributes are considered:
X
X blocks (no innermost blocks):
X 1. Length (in lines)
X 2. Number of ';'
X 3. Nesting depth
X 4. Total number of enclosed blocks
X 5. Maximum absolute nesting depth of enclosed blocks
X
X innermost blocks:
X 6. Length (in lines)
X 7. Number of ';'
X 8. Nesting depth
X
X all blocks (also innermost):
X 9. Length (in lines)
X 10. Number of ';'
X 11. Nesting depth
X
X innermost blocks & bodies of all blockless functions:
X 12. Length (in lines)
X 13. Number of ';'
X 14. Nesting depth
X
X all blocks (also innermost) & bodies of all functions:
X 15. Length (in lines)
X 16. Number of ';'
X 17. Nesting depth
X
X
X
X
X=============================================================================
X3. How to use 'statty' program
X=============================================================================
X
XUsage: statty [ -c ] basename [ + exclude-files - ] input-files
X
X'statty' executes 'stattyM', 'stattyF', 'stattyCSE' and 'stattyB' one after
Xanother. The advantage of 'statty' is that the expansion of wildcard
Xexpressions in the command line is carried out only once. That's more effi-
Xcient. If the -c option is used, 'statty' asks you to confirm before each
Xreport. If you answer in the negative the next report will be offered.
XYou will find
X
X the module report in 'basename.M',
X the function report in 'basename.F',
X the control structure & expression report in 'basename.CSE',
X the block report in 'basename.B'.
X
XSee 2.I for the handling of 'exclude-files'.
X
XTake care that the four tools are in the current working directory or in
Xyour $PATH.
X
X=============================================================================
END_OF_FILE
if test 8697 -ne `wc -c <'Ccount/README.2'`; then
echo shar: \"'Ccount/README.2'\" unpacked with wrong size!
fi
# end of 'Ccount/README.2'
fi
if test -f 'Ccount/statty' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Ccount/statty'\"
else
echo shar: Extracting \"'Ccount/statty'\" \(2188 characters\)
sed "s/^X//" >'Ccount/statty' <<'END_OF_FILE'
X#!/tools/perl/bin/perl
X
X#############################################################################
X#
X# Usage: statty [ -c ] basename [ + exclude-files - ] input-files
X#
X# 'statty' reads data files in 'ccount' output format and give statistical
X# reports about modules, functions, blocks, control structures and
X# expressions of C source files.
X# It executes 'stattyM', 'stattyF', 'stattyCSE' and 'stattyB' one after
X# the other. If the -c option is used, 'statty' will ask you to confirm
X# before each report. If you answer in the negative the next report will
X# be offered.
X# The report filenames are 'basename.M', 'basename.F', 'basename.CSE' and
X# 'basename.B'.
X# See 'README.1' and 'README.2' for more details!
X#
X# Author: Joerg Lawrenz, Universitaet Karlsruhe
X# Date: 93/12/1
X#
X#############################################################################
X
X#
X# First get the -c option.
X#
X
Xif ($ARGV[0] eq "-c") {
X $switch = 1;
X shift;
X
X }
X
X#
X# Exit if there are not enough arguments in the command line.
X#
X
Xif (scalar(@ARGV) < 2) {
X print "Usage: statty [ -c ] basename [ + exclude-files - ] input-files\n";
X exit;
X}
X
X#
X# Now get the basename for the single report names.
X#
X
X$basename = shift;
X
X#
X# Now start the single report tools.
X#
X$reportname = $basename.".M";
Xprint "Module report...\n";
X`stattyM $reportname @ARGV` if &yes;
X
X$reportname = $basename.".F";
Xprint "Function report...\n";
X`stattyF $reportname @ARGV` if &yes;
X
X#
X# Now delete the exclude-files from the list.
X#
X
Xif ($ARGV[0] eq '+') {
X shift;
X while ($ARGV[0] ne '-') {
X shift;
X }
X shift;
X}
X
X$reportname = $basename.".CSE";
Xprint "Control Structures & Expression report...\n";
X`stattyCSE $reportname @ARGV` if &yes;
X
X$reportname = $basename.".B";
Xprint "Block report...\n";
X`stattyB $reportname @ARGV` if &yes;
X
X
X#############################################################################
X#
X# 'yes' is the request subroutine.
X#
X#############################################################################
X
Xsub yes {
X if ($switch) {
X print STDOUT "Confirm (y/n): ";
X local($answer) = scalar(<STDIN>);
X $answer =~ /^y/i;
X }
X else {
X 1;
X }
X}
END_OF_FILE
if test 2188 -ne `wc -c <'Ccount/statty'`; then
echo shar: \"'Ccount/statty'\" unpacked with wrong size!
fi
chmod +x 'Ccount/statty'
# end of 'Ccount/statty'
fi
if test -f 'Ccount/stattyB' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Ccount/stattyB'\"
else
echo shar: Extracting \"'Ccount/stattyB'\" \(7315 characters\)
sed "s/^X//" >'Ccount/stattyB' <<'END_OF_FILE'
X#!/tools/perl/bin/perl
X
X#############################################################################
X#
X# Usage: stattyB report-filename input-files
X#
X# 'stattyB' reads data files in 'ccount' output format and gives a
X# statistical report about the structure of blocks in C source files.
X# See 'README.1' and 'README.2' for more details!
X#
X# Author: Joerg Lawrenz, Universitaet Karlsruhe
X# Date: 93/12/1
X#
X#############################################################################
X
X#
X# First get the report-filename
X#
X
X$file = shift;
X
X#
X# Exit if there are not enough arguments in the command line.
X#
X
Xif (scalar(@ARGV) == 0) {
X print STDERR "Usage: stattyB report-filename input-files\n";
X exit;
X}
X
X#
X# Get the names of the first and the last file for later report information.
X#
X
X$FirstFile = $ARGV[0];
X$LastFile = $ARGV[$#ARGV];
X
X#
X# Now read all input files line by line, count blocks, innermost blocks
X# and functions, accumulates for their attribute field values the according
X# histograms and count the modules.
X# Consider attribute combinations of blocks, innermost blocks and function
X# bodies:
X# $BI... : all blocks + all innermost blocks
X# $FI... : bodies of all blockless functions + innermost blocks
X# $BIF... : all blocks + innermost blocks + bodies of all functions
X#
X
Xwhile (<>) {
X if (/^B/) {
X split;
X $BlockLines {$_[1]}++;
X $BlockSemis {$_[2]}++;
X $BlockDepth {$_[3]}++;
X $BlockBlocks {$_[4]}++;
X $BlockMaxDepth{$_[5]}++;
X $BIFLines{$_[1]}++;
X $BIFSemis{$_[2]}++;
X $BIFDepth{$_[3]}++;
X $BILines{$_[1]}++;
X $BISemis{$_[2]}++;
X $BIDepth{$_[3]}++;
X $blocks++;
X next;
X }
X if (/^F/) {
X split;
X $BIFLines{$_[2]}++;
X $BIFSemis{$_[4]}++;
X $BIFDepth{1}++;
X if ($_[11] == 0) {
X $FILines{$_[2]}++;
X $FISemis{$_[4]}++;
X $FIDepth{1}++;
X $NoBlockFunctions++;
X }
X $functions++;
X next;
X }
X if (/^I/) {
X split;
X $InBlockLines{$_[1]}++;
X $InBlockSemis{$_[2]}++;
X $InBlockDepth{$_[3]}++;
X $BIFLines{$_[1]}++;
X $BIFSemis{$_[2]}++;
X $BIFDepth{$_[3]}++;
X $BILines{$_[1]}++;
X $BISemis{$_[2]}++;
X $BIDepth{$_[3]}++;
X $FILines{$_[1]}++;
X $FISemis{$_[2]}++;
X $FIDepth{$_[3]}++;
X $inblocks++;
X next;
X }
X $module++ if /^M/;
X}
X
X#
X# If no modules found, quit.
X#
X
Xif (!$module) {
X print STDERR "No modules found!\n";
X exit;
X}
X
X#
X# Now write the report by inserting for each attribute histogram
X# the statistical results of the subroutine 'stat'.
X#
X
Xopen(FILE, "> $file");
X
Xchop($cwd = `pwd`);
X
Xprint FILE "BLOCK REPORT (from $cwd: $FirstFile ... $LastFile):\n\n";
X
Xprint FILE " Average Std.dev. Max. 25q [%] 50q [%] 75q [%] 90q [%] 95q [%] 98q [%] 99q [%]\n";
Xprint FILE " ------- -------- ------ -------------- -------------- -------------- -------------- -------------- -------------- --------------";
Xprint FILE "\n---- BLOCKS ----\n";
X&printd('lines', &stat(*BlockLines));
X&printd('";"', &stat(*BlockSemis));
X&printd('depth', &stat(*BlockDepth));
X&printd('subblocks', &stat(*BlockBlocks));
X&printd('Max. depth/1', &stat(*BlockMaxDepth));
X
Xprint FILE "\nINNERMOST BLOCKS\n";
X&printd('lines', &stat(*InBlockLines));
X&printd('";"', &stat(*InBlockSemis));
X&printd('depth', &stat(*InBlockDepth));
X
Xprint FILE "\n------ BI ------\n";
X&printd('lines', &stat(*BILines));
X&printd('";"', &stat(*BISemis));
X&printd('depth', &stat(*BIDepth));
X
Xprint FILE "\n----- FI ------\n";
X&printd('lines', &stat(*FILines));
X&printd('";"', &stat(*FISemis));
X&printd('depth', &stat(*FIDepth));
X
Xprint FILE "\n----- BIF ------\n";
X&printd('lines', &stat(*BIFLines));
X&printd('";"', &stat(*BIFSemis));
X&printd('depth', &stat(*BIFDepth));
X
Xprintf FILE "\n\n# Modules: %6d\n", $module;
Xprintf FILE "# Functions: %6d\n", $functions;
Xprintf FILE "# Blocks (not innermost): %6d\n", $blocks;
Xprintf FILE "# Innermost blocks: %6d\n", $inblocks;
Xprintf FILE "# Blockless functions: %6d\n\n", $NoBlockFunctions;
X
Xprint FILE "BI := all blocks + all innermost blocks\n";
Xprint FILE "FI := bodies of all blockless functions + innermost blocks\n";
Xprint FILE "BIF := all blocks + innermost blocks + bodies of all functions\n";
X
Xprint FILE "\n/1 Maximum of all subblock nesting depths\n";
X
Xclose(FILE);
X
X
X#############################################################################
X#
X# Here is the subroutine 'stat', which calculates statistical values from
X# a given histogram.
X#
X#############################################################################
X
Xsub stat {
X local(*Array) = @_;
X local($i, $val, $sum, $num, $Average, $StdDev, $Max);
X local(@Quantil_25, @Quantil_50, @Quantil_75);
X local(@Quantil_90, @Quantil_95, @Quantil_98, @Quantil_99);
X
X# Average:
X
X while (($i,$val) = each %Array) {
X $sum += $val * $i;
X $num += $val;
X $Max = $i > $Max ? $i : $Max;
X }
X $Average = $num > 0 ? $sum/$num : 0;
X
X# Standard deviation:
X
X $sum = 0;
X while (($i,$val) = each %Array) {
X $sum += $val * ($i - $Average)**2;
X }
X $StdDev = $num > 1 ? sqrt($sum/($num-1)) : 0;
X
X# Quantils:
X
X $sum = 0;
X foreach $i (sort numerically keys %Array) {
X $sum += 100 * $Array{$i} / $num;
X
X if ($sum >= 25 && !defined @Quantil_25) {
X @Quantil_25 = ($i,$sum);
X }
X if ($sum >= 50 && !defined @Quantil_50) {
X @Quantil_50 = ($i,$sum);
X }
X if ($sum >= 75 && !defined @Quantil_75) {
X @Quantil_75 = ($i,$sum);
X }
X if ($sum >= 90 && !defined @Quantil_90) {
X @Quantil_90 = ($i,$sum);
X }
X if ($sum >= 95 && !defined @Quantil_95) {
X @Quantil_95 = ($i,$sum);
X }
X if ($sum >= 98 && !defined @Quantil_98) {
X @Quantil_98 = ($i,$sum);
X }
X if ($sum >= 99) {
X @Quantil_99 = ($i,$sum);
X last;
X }
X }
X
X# Now return all results.
X
X ($Average, $StdDev, $Max, @Quantil_25, @Quantil_50, @Quantil_75,
X @Quantil_90, @Quantil_95, @Quantil_98, @Quantil_99);
X}
X
X
X#############################################################################
X#
X# 'printd' is the right output subroutine for the combination of decimal
X# and floating point values.
X#
X#############################################################################
X
Xsub printd {
X local($object,@list) = @_;
X
X printf FILE "%-15s%7.1f %7.1f %6d %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f)\n",
X $object, @list;
X}
X
X
X#############################################################################
X#
X# 'printp' is the right output subroutine for floating point values only.
X#
X#############################################################################
X
Xsub printp {
X local($object,@list) = @_;
X
X printf FILE "%-15s%7.1f %7.1f %6.1f %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f)\n", $object, @list;
X}
X
X
X#############################################################################
X#
X# This subroutine compares two values. It is used by a sorting routine
X# in 'stat'.
X#
X#############################################################################
X
Xsub numerically { $a <=> $b; }
END_OF_FILE
if test 7315 -ne `wc -c <'Ccount/stattyB'`; then
echo shar: \"'Ccount/stattyB'\" unpacked with wrong size!
fi
chmod +x 'Ccount/stattyB'
# end of 'Ccount/stattyB'
fi
if test -f 'Ccount/stattyCSE' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Ccount/stattyCSE'\"
else
echo shar: Extracting \"'Ccount/stattyCSE'\" \(7466 characters\)
sed "s/^X//" >'Ccount/stattyCSE' <<'END_OF_FILE'
X#!/tools/perl/bin/perl
X
X#############################################################################
X#
X# Usage: stattyCSE report-filename input-files
X#
X# 'stattyCSE' reads data files in 'ccount' output format and gives a
X# statistical report about control structures and expression of C
X# source files.
X# See 'README.1' and 'README.2' for more details!
X#
X# Author: Joerg Lawrenz, Universitaet Karlsruhe
X# Date: 93/12/1
X#
X#############################################################################
X
X#
X# First get the report-filename
X#
X
X$file = shift;
X
X#
X# Exit if there are not enough arguments in the command line.
X#
X
Xif (scalar(@ARGV) == 0) {
X print STDERR "Usage: stattyCSE report-filename input-files\n";
X exit;
X}
X
X#
X# Get the names of the first and the last file for later report information.
X#
X
X$FirstFile = $ARGV[0];
X$LastFile = $ARGV[$#ARGV];
X
X#
X# Now read all input files line by line, count the objects (expression,
X# 'for', 'if', 'switch', 'while'), accumulates for their attribute field
X# values the according histograms and count the modules.
X#
X
Xwhile (<>) {
X if (/^e/) {
X split;
X $ExprOps {$_[1]}++;
X $ExprDepth{$_[2]}++;
X $expr++;
X next;
X }
X if (/^f/) {
X split;
X $ForLines {$_[1]}++;
X $ForSemis {$_[2]}++;
X $ForDepth {$_[3]}++;
X $ForOps {$_[4]}++;
X $ForBreakCont{$_[5]}++;
X $for++;
X next;
X }
X if (/^i/) {
X split;
X $IfLines {$_[1]}++;
X $IfOps {$_[2]}++;
X $IfSemis{$_[4]+$_[6]}++;
X $IfPartLines {$_[3]}++;
X $IfPartSemis {$_[4]}++;
X $ElsePartLines{$_[5]}++;
X $ElsePartSemis{$_[6]}++;
X $IfDepth {$_[7]}++;
X $if++;
X next;
X }
X if (/^s/) {
X split;
X $SwitchLines{$_[1]}++;
X $SwitchSemis{$_[2]}++;
X $SwitchDepth{$_[3]}++;
X $SwitchOps {$_[4]}++;
X $SwitchCase {$_[5]}++;
X $SwitchBreak{$_[6]}++;
X $switch++;
X next;
X }
X if (/^w/) {
X split;
X $WhileLines {$_[1]}++;
X $WhileSemis {$_[2]}++;
X $WhileDepth {$_[3]}++;
X $WhileOps {$_[4]}++;
X $WhileBreakCont{$_[5]}++;
X $while++;
X next;
X }
X $module++ if /^M/;
X}
X
X#
X# If no modules found, quit.
X#
X
Xif (!$module) {
X print STDERR "No modules found!\n";
X exit;
X}
X
X#
X# Now write the report by inserting for each attribute histogram
X# the statistical results of the subroutine 'stat'.
X#
X
Xopen(FILE, "> $file");
X
Xchop($cwd = `pwd`);
X
Xprint FILE "CONTROL STRUCTURES & EXPRESSION REPORT (from $cwd: $FirstFile ... $LastFile):\n\n";
X
Xprint FILE " Average Std.dev. Max. 25q [%] 50q [%] 75q [%] 90q [%] 95q [%] 98q [%] 99q [%]\n";
Xprint FILE " ------- -------- ------ -------------- -------------- -------------- -------------- -------------- -------------- --------------";
Xprint FILE "\n----- IF -----\n";
X&printd('lines', &stat(*IfLines));
X&printd('";"', &stat(*IfSemis));
X&printd('lines if-part', &stat(*IfPartLines));
X&printd('";" if-part', &stat(*IfPartSemis));
X&printd('lines else-part',&stat(*ElsePartLines));
X&printd('";" else-part', &stat(*ElsePartSemis));
X&printd('depth', &stat(*IfDepth));
X&printd('operators/1', &stat(*IfOps));
X
Xprint FILE "\n--- WHILE ----\n";
X&printd('lines', &stat(*WhileLines));
X&printd('";"', &stat(*WhileSemis));
X&printd('"break","cont."',&stat(*WhileBreakCont));
X&printd('depth', &stat(*WhileDepth));
X&printd('operators/1', &stat(*WhileOps));
X
Xprint FILE "\n---- FOR -----\n";
X&printd('lines', &stat(*ForLines));
X&printd('";"', &stat(*ForSemis));
X&printd('"break","cont."',&stat(*ForBreakCont));
X&printd('depth', &stat(*ForDepth));
X&printd('operators/2', &stat(*ForOps));
X
Xprint FILE "\n--- SWITCH ---\n";
X&printd('lines', &stat(*SwitchLines));
X&printd('";"', &stat(*SwitchSemis));
X&printd('"case"', &stat(*SwitchCase));
X&printd('"break"', &stat(*SwitchBreak));
X&printd('depth', &stat(*SwitchDepth));
X&printd('operators/3',&stat(*SwitchOps));
X
Xprint FILE "\n- EXPRESSION/4 -\n";
X&printd('depth', &stat(*ExprDepth));
X&printd('operators', &stat(*ExprOps));
X
Xprintf FILE "\n\n# Modules: %6d\n", $module;
Xprintf FILE "# If: %6d\n", $if;
Xprintf FILE "# While: %6d\n", $while;
Xprintf FILE "# For: %6d\n", $for;
Xprintf FILE "# Switch: %6d\n", $switch;
Xprintf FILE "# Expressions: %6d\n", $expr;
X
Xprint FILE "\n/1 operators in head condition";
Xprint FILE "\n/2 operators in second expression of head";
Xprint FILE "\n/3 operators in head expression\n";
Xprint FILE "\n/4 statement followed by ';'";
X
Xclose(FILE);
X
X
X#############################################################################
X#
X# Here is the subroutine 'stat', which calculates statistical values from
X# a given histogram.
X#
X#############################################################################
X
Xsub stat {
X local(*Array) = @_;
X local($i, $val, $sum, $num, $Average, $StdDev, $Max);
X local(@Quantil_25, @Quantil_50, @Quantil_75);
X local(@Quantil_90, @Quantil_95, @Quantil_98, @Quantil_99);
X
X# Average:
X
X while (($i,$val) = each %Array) {
X $sum += $val * $i;
X $num += $val;
X $Max = $i > $Max ? $i : $Max;
X }
X $Average = $num > 0 ? $sum/$num : 0;
X
X# Standard deviation:
X
X $sum = 0;
X while (($i,$val) = each %Array) {
X $sum += $val * ($i - $Average)**2;
X }
X $StdDev = $num > 1 ? sqrt($sum/($num-1)) : 0;
X
X# Quantils:
X
X $sum = 0;
X foreach $i (sort numerically keys %Array) {
X $sum += 100 * $Array{$i} / $num;
X
X if ($sum >= 25 && !defined @Quantil_25) {
X @Quantil_25 = ($i,$sum);
X }
X if ($sum >= 50 && !defined @Quantil_50) {
X @Quantil_50 = ($i,$sum);
X }
X if ($sum >= 75 && !defined @Quantil_75) {
X @Quantil_75 = ($i,$sum);
X }
X if ($sum >= 90 && !defined @Quantil_90) {
X @Quantil_90 = ($i,$sum);
X }
X if ($sum >= 95 && !defined @Quantil_95) {
X @Quantil_95 = ($i,$sum);
X }
X if ($sum >= 98 && !defined @Quantil_98) {
X @Quantil_98 = ($i,$sum);
X }
X if ($sum >= 99) {
X @Quantil_99 = ($i,$sum);
X last;
X }
X }
X
X# Now return all results.
X
X ($Average, $StdDev, $Max, @Quantil_25, @Quantil_50, @Quantil_75,
X @Quantil_90, @Quantil_95, @Quantil_98, @Quantil_99);
X}
X
X
X#############################################################################
X#
X# 'printd' is the right output subroutine for the combination of decimal
X# and floating point values.
X#
X#############################################################################
X
Xsub printd {
X local($object,@list) = @_;
X
X printf FILE "%-15s%7.1f %7.1f %6d %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f)\n",
X $object, @list;
X}
X
X
X#############################################################################
X#
X# 'printp' is the right output subroutine for floating point values only.
X#
X#############################################################################
X
Xsub printp {
X local($object,@list) = @_;
X
X printf FILE "%-15s%7.1f %7.1f %6.1f %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f)\n", $object, @list;
X}
X
X
X#############################################################################
X#
X# This subroutine compares two values. It is used by a sorting routine
X# in 'stat'.
X#
X#############################################################################
X
Xsub numerically { $a <=> $b; }
END_OF_FILE
if test 7466 -ne `wc -c <'Ccount/stattyCSE'`; then
echo shar: \"'Ccount/stattyCSE'\" unpacked with wrong size!
fi
chmod +x 'Ccount/stattyCSE'
# end of 'Ccount/stattyCSE'
fi
if test -f 'Ccount/stattyF' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Ccount/stattyF'\"
else
echo shar: Extracting \"'Ccount/stattyF'\" \(7152 characters\)
sed "s/^X//" >'Ccount/stattyF' <<'END_OF_FILE'
X#!/tools/perl/bin/perl
X
X#############################################################################
X#
X# Usage: stattyF report-filename [ + exclude-files - ] input-files
X#
X# 'stattyF' reads data files in 'ccount' output format and gives a
X# statistical report about the structure of functions in C source files.
X# See 'README.1' and 'README.2' for more details!
X#
X# Author: Joerg Lawrenz, Universitaet Karlsruhe
X# Date: 93/12/1
X#
X#############################################################################
X
X#
X# First get the report-filename
X#
X
X$file = shift;
X
X#
X# Now save the names of the exclude-files and count them.
X#
X
Xif ($ARGV[0] eq '+') {
X shift;
X $FirstExcludeFile = $ARGV[0];
X while ($ARGV[0] ne '-') {
X $filename = shift;
X $EXclude{$filename}++;
X $Mexclude++;
X if (scalar(@ARGV) == 0) {
X print STDERR "Usage: stattyF report-filename [ + exclude-files - ] input-files\n";
X exit;
X }
X }
X shift;
X $LastExcludeFile = $filename;
X}
X
X#
X# Exit if there are not enough arguments in the command line.
X#
X
Xif (scalar(@ARGV) == 0) {
X print STDERR "Usage: stattyF report-filename [ + exclude-files - ] input-files\n";
X exit;
X}
X
X#
X# Get the names of the first and the last file for later report information.
X#
X
X$FirstFile = $ARGV[0];
X$LastFile = $ARGV[$#ARGV];
X
X#
X# Now read all input files line by line, accumulates for the function
X# attribute field values and for calculations from them the according
X# histograms, and count the functions and the modules.
X#
X
Xwhile (<>) {
X if (/^F/) {
X split;
X
X# For the first 5 attributes, accumulate the histograms only if the
X# current function results are not in a exclude-file.
X
X if (!$EXclude{$ARGV}) {
X $BYTES{$_[1]}++;
X $LINES{$_[2]}++;
X $ByteLineQuotient { sprintf("%.1f", $_[1]/$_[2]) } ++;
X $Comment{$_[3]}++;
X $CommentPortion { sprintf("%.1f", 100*$_[3]/$_[1]) } ++;
X }
X else {
X $Fexclude++;
X }
X $SEMIS {$_[4]}++;
X $IF {$_[5]}++;
X $WHILE {$_[6]}++;
X $FOR {$_[7]}++;
X $SWITCH{$_[8]}++;
X $GOTO {$_[9]}++;
X $LABEL {$_[10]}++;
X $BLOCKS{$_[11]}++;
X $AveInblockLen{$_[12]}++;
X $DevInblockLen{$_[13]}++;
X $MaxInblockLen{$_[14]}++;
X $AveDepth{$_[15]}++;
X $DevDepth{$_[16]}++;
X $MaxDepth{$_[17]}++;
X $functions++;
X }
X $module++ if /^M/;
X}
X
X#
X# If no functions found, quit.
X#
X
Xif (!$functions) {
X print STDERR "No functions found!\n";
X exit;
X}
X
X#
X# Now write the report by inserting for each attribute histogram
X# the statistical results of the subroutine 'stat'.
X#
X
Xopen(FILE, "> $file");
X
Xchop($cwd = `pwd`);
X
Xprint FILE "FUNCTION REPORT (from $cwd: $FirstFile ... $LastFile, excluded(~): $FirstExcludeFile ... $LastExcludeFile):\n\n";
X
Xprint FILE " Average Std.dev. Max. 25q [%] 50q [%] 75q [%] 90q [%] 95q [%] 98q [%] 99q [%]\n";
Xprint FILE " ------- -------- ------ -------------- -------------- -------------- -------------- -------------- -------------- --------------\n";
X&printd('bytes~', &stat(*BYTES));
X&printd('lines~', &stat(*LINES));
X&printp('bytes/line~', &stat(*ByteLineQuotient));
X
Xprint FILE "\nComment~:\n";
X&printd('bytes', &stat(*Comment));
X&printp('portion', &stat(*CommentPortion));
X
Xprint FILE "\n";
X&printd('if', &stat(*IF));
X&printd('while', &stat(*WHILE));
X&printd('for', &stat(*FOR));
X&printd('switch', &stat(*SWITCH));
X&printd('goto', &stat(*GOTO));
X&printd('label', &stat(*LABEL));
X
Xprint FILE "\n";
X&printd('";"', &stat(*SEMIS));
X&printd('blocks', &stat(*BLOCKS));
X
Xprint FILE "\nInnermost block length in ';' (*):\n";
X&printp('Average', &stat(*AveInblockLen));
X&printp('Std.dev.',&stat(*DevInblockLen));
X&printd('Maximum', &stat(*MaxInblockLen));
X
Xprint FILE "\nBlock nesting depth:\n";
X&printp('Average', &stat(*AveDepth));
X&printp('Std.dev.',&stat(*DevDepth));
X&printd('Maximum', &stat(*MaxDepth));
X
Xprint FILE "\n\nModules: $module\n";
Xprint FILE "Functions: $functions\n\n";
Xprintf FILE "~ Excluded: %d functions in %d modules\n",
X $Fexclude, $Mexclude;
Xprint FILE "\n";
Xprint FILE "(*) + blockless functions\n";
Xclose(FILE);
X
X
X#############################################################################
X#
X# Here is the subroutine 'stat', which calculates statistical values from
X# a given histogram.
X#
X#############################################################################
X
Xsub stat {
X local(*Array) = @_;
X local($i, $val, $sum, $num, $Average, $StdDev, $Max);
X local(@Quantil_25, @Quantil_50, @Quantil_75);
X local(@Quantil_90, @Quantil_95, @Quantil_98, @Quantil_99);
X
X# Average:
X
X while (($i,$val) = each %Array) {
X $sum += $val * $i;
X $num += $val;
X $Max = $i > $Max ? $i : $Max;
X }
X $Average = $num > 0 ? $sum/$num : 0;
X
X# Standard Deviation:
X
X $sum = 0;
X while (($i,$val) = each %Array) {
X $sum += $val * ($i - $Average)**2;
X }
X $StdDev = $num > 1 ? sqrt($sum/($num-1)) : 0;
X
X# Quantils:
X
X $sum = 0;
X foreach $i (sort numerically keys %Array) {
X $sum += 100 * $Array{$i} / $num;
X
X if ($sum >= 25 && !defined @Quantil_25) {
X @Quantil_25 = ($i,$sum);
X }
X if ($sum >= 50 && !defined @Quantil_50) {
X @Quantil_50 = ($i,$sum);
X }
X if ($sum >= 75 && !defined @Quantil_75) {
X @Quantil_75 = ($i,$sum);
X }
X if ($sum >= 90 && !defined @Quantil_90) {
X @Quantil_90 = ($i,$sum);
X }
X if ($sum >= 95 && !defined @Quantil_95) {
X @Quantil_95 = ($i,$sum);
X }
X if ($sum >= 98 && !defined @Quantil_98) {
X @Quantil_98 = ($i,$sum);
X }
X if ($sum >= 99) {
X @Quantil_99 = ($i,$sum);
X last;
X }
X }
X
X# Now return all results.
X
X ($Average, $StdDev, $Max, @Quantil_25, @Quantil_50, @Quantil_75,
X @Quantil_90, @Quantil_95, @Quantil_98, @Quantil_99);
X}
X
X
X#############################################################################
X#
X# 'printd' is the right output subroutine for the combination of decimal
X# and floating point values.
X#
X#############################################################################
X
Xsub printd {
X local($object,@list) = @_;
X
X printf FILE "%-14s %6.1f %6.1f %6d %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f)\n",
X $object, @list;
X}
X
X
X#############################################################################
X#
X# 'printp' is the right output subroutine for floating point values only.
X#
X#############################################################################
X
Xsub printp {
X local($object,@list) = @_;
X
X printf FILE "%-14s %6.1f %6.1f %6.1f %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f)\n", $object, @list;
X}
X
X
X#############################################################################
X#
X# This subroutine compares two values. It is used by a sorting routine
X# in 'stat'.
X#
X#############################################################################
X
Xsub numerically { $a <=> $b; }
END_OF_FILE
if test 7152 -ne `wc -c <'Ccount/stattyF'`; then
echo shar: \"'Ccount/stattyF'\" unpacked with wrong size!
fi
chmod +x 'Ccount/stattyF'
# end of 'Ccount/stattyF'
fi
if test -f 'Ccount/stattyM' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Ccount/stattyM'\"
else
echo shar: Extracting \"'Ccount/stattyM'\" \(7905 characters\)
sed "s/^X//" >'Ccount/stattyM' <<'END_OF_FILE'
X#!/tools/perl/bin/perl
X
X#############################################################################
X#
X# Usage: stattyM report-filename [ + exclude-files - ] input-files
X#
X# 'stattyM' reads data files in 'ccount' output format and gives a
X# statistical report about the structure of modules in C source files
X# (only global results are considered here).
X# See 'README.1' and 'README.2' for more details!
X#
X# Author: Joerg Lawrenz, Universitaet Karlsruhe
X# Date: 93/12/1
X#
X#############################################################################
X
X#
X# First get the report-filename
X#
X
X$file = shift;
X
X#
X# Now save the names of the exclude-files and count them.
X#
X
Xif ($ARGV[0] eq '+') {
X shift;
X $FirstExcludeFile = $ARGV[0];
X while ($ARGV[0] ne '-') {
X $filename = shift;
X $EXclude{$filename}++;
X $Mexclude++;
X if (scalar(@ARGV) == 0) {
X print STDERR "Usage: stattyM report-filename [ + exclude-files - ] input-files\n";
X exit;
X }
X }
X shift;
X $LastExcludeFile = $filename;
X}
X
X#
X# Exit if there are not enough arguments in the command line.
X#
X
Xif (scalar(@ARGV) == 0) {
X print STDERR "Usage: stattyM report-filename [ + exclude-files - ] input-files\n";
X exit;
X}
X
X#
X# Get the names of the first and the last file for later report information.
X#
X
X$FirstFile = $ARGV[0];
X$LastFile = $ARGV[$#ARGV];
X
X#
X# Now read all input files line by line, accumulates for the module
X# attribute field values and for calculations from them the according
X# histograms, and count the modules.
X#
X
Xwhile (<>) {
X if (/^M/) {
X split;
X
X# For the first 12 attributes, accumulate the histograms only if the
X# current module results are not in a exclude-file.
X
X if (!$EXclude{$ARGV}) {
X $BYTES {$_[1]}++;
X $LINES {$_[2]}++;
X $ByteLineQuotient { sprintf("%.1f", $_[2] ? $_[1]/$_[2] : 0) } ++;
X $Comment{$_[3]}++;
X $PPcomment{$_[4]}++;
X $relevBytes = $_[6]+$_[8]+$_[10];
X $RelevBytes{$relevBytes}++;
X $BLANKS{ $_[1]-$_[3]-$_[4]-$relevBytes }++;
X
X $CommentPortion { sprintf("%.1f", 100*$_[3]/$_[1]) } ++;
X $PPCommentPortion{ sprintf("%.1f", 100*$_[4]/$_[1]) } ++;
X $RelevBytePortion{ sprintf("%.1f", 100*$relevBytes/$_[1]) } ++;
X $BlankPortion { sprintf("%.1f",
X 100 * (1 - ($_[3]+$_[4]+$relevBytes)/$_[1]) ) } ++;
X
X }
X $NumId {$_[5]}++;
X $ByteId {$_[6]}++;
X $NumSym {$_[7]}++;
X $ByteSym {$_[8]}++;
X $NumPP {$_[9]}++;
X $BytePP {$_[10]}++;
X $Semi {$_[11]}++;
X $Functions{$_[12]}++;
X $AveInblockLen{$_[13]}++;
X $DevInblockLen{$_[14]}++;
X $MaxInblockLen{$_[15]}++;
X $AveAveDepth{$_[16]}++;
X $DevAveDepth{$_[17]}++;
X $MaxAveDepth{$_[18]}++;
X $module++;
X }
X}
X
X#
X# If no modules found, quit.
X#
X
Xif (!$module) {
X print STDERR "No modules found!\n";
X exit;
X}
X
X#
X# Now write the report by inserting for each attribute histogram
X# the statistical results of the subroutine 'stat'.
X#
X
Xopen(FILE, "> $file");
X
Xchop($cwd = `pwd`);
X
Xprint FILE "MODULE REPORT (from $cwd: $FirstFile ... $LastFile, excluded(~): $FirstExcludeFile ... $LastExcludeFile):\n\n";
X
Xprint FILE " Average Std.dev. Max. 25q [%] 50q [%] 75q [%] 90q [%] 95q [%] 98q [%] 99q [%]\n";
Xprint FILE " ------- -------- ------ -------------- -------------- -------------- -------------- -------------- -------------- --------------\n";
X&printd('bytes~', &stat(*BYTES));
X&printd('lines~', &stat(*LINES));
X&printp('bytes/line~', &stat(*ByteLineQuotient));
X
Xprint FILE "\nBytes~:\n";
X&printd('Comment', &stat(*Comment));
X&printd('PPcomment', &stat(*PPcomment));
X&printd('Relev. symb.', &stat(*RelevBytes));
X&printd('"Blanks"', &stat(*BLANKS));
X
Xprint FILE "\nPortions[%]~:\n";
X&printp('Comment', &stat(*CommentPortion));
X&printp('PPcomment', &stat(*PPCommentPortion));
X&printp('Relev. symb.', &stat(*RelevBytePortion));
X&printp('"Blanks"', &stat(*BlankPortion));
X
Xprint FILE "\n";
X&printd('#identifier', &stat(*NumId));
X&printd('bytes id', &stat(*ByteId));
Xprint FILE "\n";
X&printd('#symbols', &stat(*NumSym));
X&printd('bytes sym', &stat(*ByteSym));
Xprint FILE "\n";
X&printd('#PP-directives',&stat(*NumPP));
X&printd('bytes PP-dir', &stat(*BytePP));
X
Xprint FILE "\n";
X&printd('";"', &stat(*Semi));
X&printd('functions', &stat(*Functions));
X
Xprint FILE "\nInnermost block length in ';' (*):\n";
X&printp('Average', &stat(*AveInblockLen));
X&printp('Std.dev.', &stat(*DevInblockLen));
X&printd('Maximum', &stat(*MaxInblockLen));
X
Xprint FILE "\nAverage block nesting depth per function:\n";
X&printp('Average', &stat(*AveAveDepth));
X&printp('Std.dev', &stat(*DevAveDepth));
X&printp('Maximum', &stat(*MaxAveDepth));
X
Xprintf FILE "\n\nModules total: %5d\n", $module;
Xprintf FILE "~ Excluded: %5d\n", $Mexclude;
Xprint FILE "\n";
Xprint FILE "(*) + blockless functions\n";
Xclose(FILE);
X
X
X#############################################################################
X#
X# Here is the subroutine 'stat', which calculates statistical values from
X# a given histogram.
X#
X#############################################################################
X
Xsub stat {
X local(*Array) = @_;
X local($i, $val, $sum, $num, $Average, $StdDev, $Max);
X local(@Quantil_25, @Quantil_50, @Quantil_75);
X local(@Quantil_90, @Quantil_95, @Quantil_98, @Quantil_99);
X
X# Average:
X
X while (($i,$val) = each %Array) {
X $sum += $val * $i;
X $num += $val;
X $Max = $i > $Max ? $i : $Max;
X }
X $Average = $num > 0 ? $sum/$num : 0;
X
X# Standard Deviation:
X
X $sum = 0;
X while (($i,$val) = each %Array) {
X $sum += $val * ($i - $Average)**2;
X }
X $StdDev = $num > 1 ? sqrt($sum/($num-1)) : 0;
X
X# Quantils:
X
X $sum = 0;
X foreach $i (sort numerically keys %Array) {
X $sum += 100 * $Array{$i} / $num;
X
X if ($sum >= 25 && !defined @Quantil_25) {
X @Quantil_25 = ($i,$sum);
X }
X if ($sum >= 50 && !defined @Quantil_50) {
X @Quantil_50 = ($i,$sum);
X }
X if ($sum >= 75 && !defined @Quantil_75) {
X @Quantil_75 = ($i,$sum);
X }
X if ($sum >= 90 && !defined @Quantil_90) {
X @Quantil_90 = ($i,$sum);
X }
X if ($sum >= 95 && !defined @Quantil_95) {
X @Quantil_95 = ($i,$sum);
X }
X if ($sum >= 98 && !defined @Quantil_98) {
X @Quantil_98 = ($i,$sum);
X }
X if ($sum >= 99) {
X @Quantil_99 = ($i,$sum);
X last;
X }
X }
X
X# Now return all results.
X
X ($Average, $StdDev, $Max, @Quantil_25, @Quantil_50, @Quantil_75,
X @Quantil_90, @Quantil_95, @Quantil_98, @Quantil_99);
X}
X
X
X#############################################################################
X#
X# 'printd' is the right output subroutine for the combination of decimal
X# and floating point values.
X#
X#############################################################################
X
Xsub printd {
X local($object,@list) = @_;
X
X printf FILE "%-15s%7.1f %7.1f %6d %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f) %6d (%5.1f)\n",
X $object, @list;
X}
X
X
X#############################################################################
X#
X# 'printp' is the right output subroutine for floating point values only.
X#
X#############################################################################
X
Xsub printp {
X local($object,@list) = @_;
X
X printf FILE "%-15s%7.1f %7.1f %6.1f %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f) %6.1f (%5.1f)\n", $object, @list;
X}
X
X
X#############################################################################
X#
X# This subroutine compares two values. It is used by a sorting routine
X# in 'stat'.
X#
X#############################################################################
X
Xsub numerically { $a <=> $b; }
END_OF_FILE
if test 7905 -ne `wc -c <'Ccount/stattyM'`; then
echo shar: \"'Ccount/stattyM'\" unpacked with wrong size!
fi
chmod +x 'Ccount/stattyM'
# end of 'Ccount/stattyM'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...