home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i015: Tools for generating software metrics, Part08/14
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- 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
-
-
-