v20i015: Tools for generating software metrics, Part08/14
Rich Salz
rsalz at uunet.uu.net
Wed Sep 20 04:46:37 AEST 1989
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 at 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 at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.
More information about the Comp.sources.unix
mailing list