[comp.sources.unix] v20i015: Tools for generating software metrics, Part08/14

rsalz@uunet.uu.net (Rich Salz) (09/20/89)

Submitted-by: Brian Renaud <huron.ann-arbor.mi.us!bdr>
Posting-number: Volume 20, Issue 15
Archive-name: metrics/part08

---- Cut Here and unpack ----
#!/bin/sh
# this is part 8 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/halstead/c_halsfilt_c continued
#
CurArch=8
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file src/halstead/c_halsfilt_c"
sed 's/^X//' << 'SHAR_EOF' >> src/halstead/c_halsfilt_c
X# ifdef LEXDEBUG
X				if(debug){
X					fprintf(yyout,"try fall back character ");
X					allprint(YYU(yymatch[yych]));
X					putchar('\n');
X					}
X# endif
X				if(yyt <= yytop && yyt->verify+yysvec == yystate){
X					if(yyt->advance+yysvec == YYLERR)	/* error transition */
X						{unput(*--yylastch);break;}
X					*lsp++ = yystate = yyt->advance+yysvec;
X					goto contin;
X					}
X				}
X			if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){
X# ifdef LEXDEBUG
X				if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1);
X# endif
X				goto tryagain;
X				}
X# endif
X			else
X				{unput(*--yylastch);break;}
X		contin:
X# ifdef LEXDEBUG
X			if(debug){
X				fprintf(yyout,"state %d char ",yystate-yysvec-1);
X				allprint(yych);
X				putchar('\n');
X				}
X# endif
X			;
X			}
X# ifdef LEXDEBUG
X		if(debug){
X			fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1);
X			allprint(yych);
X			putchar('\n');
X			}
X# endif
X		while (lsp-- > yylstate){
X			*yylastch-- = 0;
X			if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){
X				yyolsp = lsp;
X				if(yyextra[*yyfnd]){		/* must backup */
X					while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){
X						lsp--;
X						unput(*yylastch--);
X						}
X					}
X				yyprevious = YYU(*yylastch);
X				yylsp = lsp;
X				yyleng = yylastch-yytext+1;
X				yytext[yyleng] = 0;
X# ifdef LEXDEBUG
X				if(debug){
X					fprintf(yyout,"\nmatch ");
X					sprint(yytext);
X					fprintf(yyout," action %d\n",*yyfnd);
X					}
X# endif
X				return(*yyfnd++);
X				}
X			unput(*yylastch);
X			}
X		if (yytext[0] == 0  /* && feof(yyin) */)
X			{
X			yysptr=yysbuf;
X			return(0);
X			}
X		yyprevious = yytext[0] = input();
X		if (yyprevious>0)
X			output(yyprevious);
X		yylastch=yytext;
X# ifdef LEXDEBUG
X		if(debug)putchar('\n');
X# endif
X		}
X	}
Xyyback(p, m)
X	int *p;
X{
Xif (p==0) return(0);
Xwhile (*p)
X	{
X	if (*p++ == m)
X		return(1);
X	}
Xreturn(0);
X}
X	/* the following are only used in the lex library */
Xyyinput(){
X	return(input());
X	}
Xyyoutput(c)
X  int c; {
X	output(c);
X	}
Xyyunput(c)
X   int c; {
X	unput(c);
X	}
SHAR_EOF
echo "File src/halstead/c_halsfilt_c is complete"
chmod 0644 src/halstead/c_halsfilt_c || echo "restore of src/halstead/c_halsfilt_c fails"
echo "x - extracting src/halstead/halstead.sh (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/halstead/halstead.sh
X: compute halstead volume of input
X# see DeMarco "Controlling Software Projects, Management, Measurement
X# and Estimation", appendix D
X# algorithm
X# 	strip comments
X#	remove strings
X#	remove delimiters
X#	deal with *++var and *--var usages
X#	break input into tokens
X#	sort - to produce total number of tokens
X#	uniq - to get size of vocabulary
X#	volume = <token count> * log2 ( vocabulary size )
X
X#	n1 == number of unique operators
X#	n2 == number of unique operands
X#	N1 == number of total operators
X#	N2 == number of total operands
X 
XN1=/tmp/$$.N1
XN2=/tmp/$$.N2
Xn1=/tmp/$$.n1
Xn2=/tmp/$$.n2
X
Xtrap '/bin/rm -f ${n1} ${n2} ${N1} ${N2} ; exit 1' 1 2 15
X
Xif [ $# -lt 1 ]
Xthen
X	echo "usage: $0 <file> [<file>]"
X	exit 1
Xfi
X
Xfor file in $*
Xdo
X	stripcom ${file} | stripstr |\
X	c_halsfilt 2> ${N1} |\
X	awk ' { for ( i = 1; i <= NF; i++) print $i; } ' |\
X	sort > ${N2}
X
X	sort -u ${N1} > ${n1}
X	uniq < ${N2} > ${n2}
X
X	wc -l ${n1} ${n2} ${N1} ${N2} |\
X	awk '
X	BEGIN {
X		File = "'"${file}"'";
X		if ( !getline )
X			printf("%s: no line count for n1\n", "'"$0"'");
X		u_opators = $1;
X
X		if ( !getline )
X			printf("%s: no line count for n2\n", "'"$0"'");
X		u_opands = $1;
X
X		if ( !getline )
X			printf("%s: no line count for N1\n", "'"$0"'");
X		t_opators = $1;
X
X		if ( !getline )
X			printf("%s: no line count for N2\n", "'"$0"'");
X		t_opands = $1;
X
X		# program length: N = N1 + N2
X		#
X		pg_length = t_opators + t_opands;
X
X		# program volume: V = N log<base2> (n1 + n2)
X		#
X		pg_volume = pg_length * (log(u_opators + u_opands)/log(2));
X
X		# program level: L = (2/n1) * (n2/N2)
X		# 2 is number of operators in smallest possible program
X		#
X		pg_level = (2 / u_opators) * (u_opands / t_opands);
X
X		# estimated effective mental discriminations: E^ = V / L
X		#
X		mental_disc = pg_volume / pg_level;
X
X		# estimated mental discriminations per second in C: 50
X		# I assume performance is normally distributed
X		# therefore per hour: 180,000
X		# so estimated time to program: T^ = E^ / 180,000 
X		# DOES NOT SEEM VERY ACCURATE FOR LARGE PROGRAMS
X		# ALL TIME STUFF REMOVED VIA COMMENTS
X		#time = mental_disc / 180000;
X
X		# print File N V L E^ T^
X		#printf("%s\t%d\t%.0f\t%.6f\t%.0f\t%.1f\n",\
X		#	File, pg_length, pg_volume, pg_level, mental_disc,time);
X
X		# print File N V L E^
X		printf("%s\t%d\t%.0f\t%.6f\t%.0f\n",\
X			File, pg_length, pg_volume, pg_level, mental_disc);
X		exit;
X	}
X	'
Xdone
X
X/bin/rm ${n1} ${n2} ${N1} ${N2}
Xexit 0
SHAR_EOF
chmod 0644 src/halstead/halstead.sh || echo "restore of src/halstead/halstead.sh fails"
echo "x - extracting src/halstead/test.result (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/halstead/test.result
Xtest1.c	619	4130	0.014966	275975
Xtest2.y	1003	7043	0.017320	406675
Xtest3.c	1234	8652	0.008107	1067162
SHAR_EOF
chmod 0644 src/halstead/test.result || echo "restore of src/halstead/test.result fails"
echo "x - extracting src/halstead/README (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/halstead/README
XOn SCO Xenix '286 Version 2.2.1, a Sun4 and a Sun386i "make test"
Xproduced the following results for test3.c:
X
X     test3.c	1234	8652	0.008107	1067161
X
XThe ``mental discriminations'' value (1067161) is one less than the
Xstandard.  Since the validity of this number is questionable, I guess
Xit's no big deal.
SHAR_EOF
chmod 0644 src/halstead/README || echo "restore of src/halstead/README fails"
echo "x - extracting src/kdsi/Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/kdsi/Makefile
X# makefile for kdsi a source lines of code counter
X
XBIN=../bin
XTEST=../testfiles
X
XCFLAGS= -O
XLDFLAGS= 
X
Xkdsi:
X	$(CC) $(CFLAGS) $(LDFLAGS) -o kdsi kdsi.c
X
Xinstall:
X	mv kdsi $(BIN)/kdsi
X	chmod 755 $(BIN)/kdsi
X
Xclean:
X	-rm -f core kdsi *.o _test
X	
Xtest:
X	@echo results of this command should be the same as test.result
X	@cp $(TEST)/test1.c $(TEST)/test2.y $(TEST)/test3.c .
X	kdsi test1.c test2.y test3.c > _test
X	diff _test test.result
X	@/bin/rm -f test1.c test2.y test3.c
SHAR_EOF
chmod 0644 src/kdsi/Makefile || echo "restore of src/kdsi/Makefile fails"
echo "x - extracting src/kdsi/kdsi.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/kdsi/kdsi.c
X/* counts number of statements, lines of code, comments, comment lines
X * and blank lines
X */
X/***************************************************************************
X* kdsi is written by Brian Renaud, is in the public domain, and            *
X* may be used by any person or organization, in any way and for any        *
X* purpose.                                                                 *
X*                                                                          *
X* There is no warranty of merchantability nor any warranty of fitness for  *
X* a particular purpose nor any other warranty, either express or implied,  *
X* as to the accuracy of the enclosed materials or as to their suitability  *
X* for any particular purpose.  Accordingly, I assume no responsibility     *
X* for their use by the recipient.  Further, I assume no obligation to      *
X* furnish any assistance of any kind whatsoever, or to furnish any         *
X* additional information or documentation.                                 *
X*                                                                          *
X* address as of July 1988: bdr%huron.uucp@umix.cc.umich.edu also known as: *
X*                          {ames, apollo, rutgers, uunet}!umix!huron!bdr   *
X***************************************************************************/
X
X#include <stdio.h>
X
Xtypedef	int	Token;
X#define	STOP_INPUT	0
X#define	NEWLINE	1
X#define START_COMMENT	2
X#define END_COMMENT	3
X#define	MISC_CHARACTER	4
X#define WHITE_SPACE	5
X
Xtypedef char	Bool;
X#define True	1
X#define False	0
X
Xtypedef int	State;
X#define	Code	0
X#define Comment	1
X#define Quiescent	2
X
X#define FNULL	( (FILE *) 0)
X#define CNULL	( (char *) 0)
X
XBool	only_stdin = False;		/* true if reading from stdin */
X
Xmain(argc, argv)
X	int	argc;
X	char	*argv[];
X{
X	Token	GetChar();
X	FILE	*nextfp();
X	register Token	input;
X	register State	statevar = Quiescent, laststate = Quiescent;
X	FILE	*fp;
X	char	*filename;
X	int	filecount = 0;
X	long	cod_linect, com_linect, blnk_linect, comment_ct;
X	long	tot_cdline, tot_cmline, tot_bkline, tot_comment;
X	Bool	following_com = False;
X
SHAR_EOF
echo "End of part 8"
echo "File src/kdsi/kdsi.c is continued in part 9"
echo "9" > s2_seq_.tmp
exit 0


-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.