home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / metrics / part08 < prev    next >
Encoding:
Internet Message Format  |  1989-09-18  |  9.4 KB

  1. Subject:  v20i015:  Tools for generating software metrics, Part08/14
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Brian Renaud <huron.ann-arbor.mi.us!bdr>
  7. Posting-number: Volume 20, Issue 15
  8. Archive-name: metrics/part08
  9.  
  10. ---- Cut Here and unpack ----
  11. #!/bin/sh
  12. # this is part 8 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file src/halstead/c_halsfilt_c continued
  15. #
  16. CurArch=8
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file src/halstead/c_halsfilt_c"
  27. sed 's/^X//' << 'SHAR_EOF' >> src/halstead/c_halsfilt_c
  28. X# ifdef LEXDEBUG
  29. X                if(debug){
  30. X                    fprintf(yyout,"try fall back character ");
  31. X                    allprint(YYU(yymatch[yych]));
  32. X                    putchar('\n');
  33. X                    }
  34. X# endif
  35. X                if(yyt <= yytop && yyt->verify+yysvec == yystate){
  36. X                    if(yyt->advance+yysvec == YYLERR)    /* error transition */
  37. X                        {unput(*--yylastch);break;}
  38. X                    *lsp++ = yystate = yyt->advance+yysvec;
  39. X                    goto contin;
  40. X                    }
  41. X                }
  42. X            if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){
  43. X# ifdef LEXDEBUG
  44. X                if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1);
  45. X# endif
  46. X                goto tryagain;
  47. X                }
  48. X# endif
  49. X            else
  50. X                {unput(*--yylastch);break;}
  51. X        contin:
  52. X# ifdef LEXDEBUG
  53. X            if(debug){
  54. X                fprintf(yyout,"state %d char ",yystate-yysvec-1);
  55. X                allprint(yych);
  56. X                putchar('\n');
  57. X                }
  58. X# endif
  59. X            ;
  60. X            }
  61. X# ifdef LEXDEBUG
  62. X        if(debug){
  63. X            fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1);
  64. X            allprint(yych);
  65. X            putchar('\n');
  66. X            }
  67. X# endif
  68. X        while (lsp-- > yylstate){
  69. X            *yylastch-- = 0;
  70. X            if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){
  71. X                yyolsp = lsp;
  72. X                if(yyextra[*yyfnd]){        /* must backup */
  73. X                    while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){
  74. X                        lsp--;
  75. X                        unput(*yylastch--);
  76. X                        }
  77. X                    }
  78. X                yyprevious = YYU(*yylastch);
  79. X                yylsp = lsp;
  80. X                yyleng = yylastch-yytext+1;
  81. X                yytext[yyleng] = 0;
  82. X# ifdef LEXDEBUG
  83. X                if(debug){
  84. X                    fprintf(yyout,"\nmatch ");
  85. X                    sprint(yytext);
  86. X                    fprintf(yyout," action %d\n",*yyfnd);
  87. X                    }
  88. X# endif
  89. X                return(*yyfnd++);
  90. X                }
  91. X            unput(*yylastch);
  92. X            }
  93. X        if (yytext[0] == 0  /* && feof(yyin) */)
  94. X            {
  95. X            yysptr=yysbuf;
  96. X            return(0);
  97. X            }
  98. X        yyprevious = yytext[0] = input();
  99. X        if (yyprevious>0)
  100. X            output(yyprevious);
  101. X        yylastch=yytext;
  102. X# ifdef LEXDEBUG
  103. X        if(debug)putchar('\n');
  104. X# endif
  105. X        }
  106. X    }
  107. Xyyback(p, m)
  108. X    int *p;
  109. X{
  110. Xif (p==0) return(0);
  111. Xwhile (*p)
  112. X    {
  113. X    if (*p++ == m)
  114. X        return(1);
  115. X    }
  116. Xreturn(0);
  117. X}
  118. X    /* the following are only used in the lex library */
  119. Xyyinput(){
  120. X    return(input());
  121. X    }
  122. Xyyoutput(c)
  123. X  int c; {
  124. X    output(c);
  125. X    }
  126. Xyyunput(c)
  127. X   int c; {
  128. X    unput(c);
  129. X    }
  130. SHAR_EOF
  131. echo "File src/halstead/c_halsfilt_c is complete"
  132. chmod 0644 src/halstead/c_halsfilt_c || echo "restore of src/halstead/c_halsfilt_c fails"
  133. echo "x - extracting src/halstead/halstead.sh (Text)"
  134. sed 's/^X//' << 'SHAR_EOF' > src/halstead/halstead.sh
  135. X: compute halstead volume of input
  136. X# see DeMarco "Controlling Software Projects, Management, Measurement
  137. X# and Estimation", appendix D
  138. X# algorithm
  139. X#     strip comments
  140. X#    remove strings
  141. X#    remove delimiters
  142. X#    deal with *++var and *--var usages
  143. X#    break input into tokens
  144. X#    sort - to produce total number of tokens
  145. X#    uniq - to get size of vocabulary
  146. X#    volume = <token count> * log2 ( vocabulary size )
  147. X
  148. X#    n1 == number of unique operators
  149. X#    n2 == number of unique operands
  150. X#    N1 == number of total operators
  151. X#    N2 == number of total operands
  152. XN1=/tmp/$$.N1
  153. XN2=/tmp/$$.N2
  154. Xn1=/tmp/$$.n1
  155. Xn2=/tmp/$$.n2
  156. X
  157. Xtrap '/bin/rm -f ${n1} ${n2} ${N1} ${N2} ; exit 1' 1 2 15
  158. X
  159. Xif [ $# -lt 1 ]
  160. Xthen
  161. X    echo "usage: $0 <file> [<file>]"
  162. X    exit 1
  163. Xfi
  164. X
  165. Xfor file in $*
  166. Xdo
  167. X    stripcom ${file} | stripstr |\
  168. X    c_halsfilt 2> ${N1} |\
  169. X    awk ' { for ( i = 1; i <= NF; i++) print $i; } ' |\
  170. X    sort > ${N2}
  171. X
  172. X    sort -u ${N1} > ${n1}
  173. X    uniq < ${N2} > ${n2}
  174. X
  175. X    wc -l ${n1} ${n2} ${N1} ${N2} |\
  176. X    awk '
  177. X    BEGIN {
  178. X        File = "'"${file}"'";
  179. X        if ( !getline )
  180. X            printf("%s: no line count for n1\n", "'"$0"'");
  181. X        u_opators = $1;
  182. X
  183. X        if ( !getline )
  184. X            printf("%s: no line count for n2\n", "'"$0"'");
  185. X        u_opands = $1;
  186. X
  187. X        if ( !getline )
  188. X            printf("%s: no line count for N1\n", "'"$0"'");
  189. X        t_opators = $1;
  190. X
  191. X        if ( !getline )
  192. X            printf("%s: no line count for N2\n", "'"$0"'");
  193. X        t_opands = $1;
  194. X
  195. X        # program length: N = N1 + N2
  196. X        #
  197. X        pg_length = t_opators + t_opands;
  198. X
  199. X        # program volume: V = N log<base2> (n1 + n2)
  200. X        #
  201. X        pg_volume = pg_length * (log(u_opators + u_opands)/log(2));
  202. X
  203. X        # program level: L = (2/n1) * (n2/N2)
  204. X        # 2 is number of operators in smallest possible program
  205. X        #
  206. X        pg_level = (2 / u_opators) * (u_opands / t_opands);
  207. X
  208. X        # estimated effective mental discriminations: E^ = V / L
  209. X        #
  210. X        mental_disc = pg_volume / pg_level;
  211. X
  212. X        # estimated mental discriminations per second in C: 50
  213. X        # I assume performance is normally distributed
  214. X        # therefore per hour: 180,000
  215. X        # so estimated time to program: T^ = E^ / 180,000 
  216. X        # DOES NOT SEEM VERY ACCURATE FOR LARGE PROGRAMS
  217. X        # ALL TIME STUFF REMOVED VIA COMMENTS
  218. X        #time = mental_disc / 180000;
  219. X
  220. X        # print File N V L E^ T^
  221. X        #printf("%s\t%d\t%.0f\t%.6f\t%.0f\t%.1f\n",\
  222. X        #    File, pg_length, pg_volume, pg_level, mental_disc,time);
  223. X
  224. X        # print File N V L E^
  225. X        printf("%s\t%d\t%.0f\t%.6f\t%.0f\n",\
  226. X            File, pg_length, pg_volume, pg_level, mental_disc);
  227. X        exit;
  228. X    }
  229. X    '
  230. Xdone
  231. X
  232. X/bin/rm ${n1} ${n2} ${N1} ${N2}
  233. Xexit 0
  234. SHAR_EOF
  235. chmod 0644 src/halstead/halstead.sh || echo "restore of src/halstead/halstead.sh fails"
  236. echo "x - extracting src/halstead/test.result (Text)"
  237. sed 's/^X//' << 'SHAR_EOF' > src/halstead/test.result
  238. Xtest1.c    619    4130    0.014966    275975
  239. Xtest2.y    1003    7043    0.017320    406675
  240. Xtest3.c    1234    8652    0.008107    1067162
  241. SHAR_EOF
  242. chmod 0644 src/halstead/test.result || echo "restore of src/halstead/test.result fails"
  243. echo "x - extracting src/halstead/README (Text)"
  244. sed 's/^X//' << 'SHAR_EOF' > src/halstead/README
  245. XOn SCO Xenix '286 Version 2.2.1, a Sun4 and a Sun386i "make test"
  246. Xproduced the following results for test3.c:
  247. X
  248. X     test3.c    1234    8652    0.008107    1067161
  249. X
  250. XThe ``mental discriminations'' value (1067161) is one less than the
  251. Xstandard.  Since the validity of this number is questionable, I guess
  252. Xit's no big deal.
  253. SHAR_EOF
  254. chmod 0644 src/halstead/README || echo "restore of src/halstead/README fails"
  255. echo "x - extracting src/kdsi/Makefile (Text)"
  256. sed 's/^X//' << 'SHAR_EOF' > src/kdsi/Makefile
  257. X# makefile for kdsi a source lines of code counter
  258. X
  259. XBIN=../bin
  260. XTEST=../testfiles
  261. X
  262. XCFLAGS= -O
  263. XLDFLAGS= 
  264. X
  265. Xkdsi:
  266. X    $(CC) $(CFLAGS) $(LDFLAGS) -o kdsi kdsi.c
  267. X
  268. Xinstall:
  269. X    mv kdsi $(BIN)/kdsi
  270. X    chmod 755 $(BIN)/kdsi
  271. X
  272. Xclean:
  273. X    -rm -f core kdsi *.o _test
  274. X    
  275. Xtest:
  276. X    @echo results of this command should be the same as test.result
  277. X    @cp $(TEST)/test1.c $(TEST)/test2.y $(TEST)/test3.c .
  278. X    kdsi test1.c test2.y test3.c > _test
  279. X    diff _test test.result
  280. X    @/bin/rm -f test1.c test2.y test3.c
  281. SHAR_EOF
  282. chmod 0644 src/kdsi/Makefile || echo "restore of src/kdsi/Makefile fails"
  283. echo "x - extracting src/kdsi/kdsi.c (Text)"
  284. sed 's/^X//' << 'SHAR_EOF' > src/kdsi/kdsi.c
  285. X/* counts number of statements, lines of code, comments, comment lines
  286. X * and blank lines
  287. X */
  288. X/***************************************************************************
  289. X* kdsi is written by Brian Renaud, is in the public domain, and            *
  290. X* may be used by any person or organization, in any way and for any        *
  291. X* purpose.                                                                 *
  292. X*                                                                          *
  293. X* There is no warranty of merchantability nor any warranty of fitness for  *
  294. X* a particular purpose nor any other warranty, either express or implied,  *
  295. X* as to the accuracy of the enclosed materials or as to their suitability  *
  296. X* for any particular purpose.  Accordingly, I assume no responsibility     *
  297. X* for their use by the recipient.  Further, I assume no obligation to      *
  298. X* furnish any assistance of any kind whatsoever, or to furnish any         *
  299. X* additional information or documentation.                                 *
  300. X*                                                                          *
  301. X* address as of July 1988: bdr%huron.uucp@umix.cc.umich.edu also known as: *
  302. X*                          {ames, apollo, rutgers, uunet}!umix!huron!bdr   *
  303. X***************************************************************************/
  304. X
  305. X#include <stdio.h>
  306. X
  307. Xtypedef    int    Token;
  308. X#define    STOP_INPUT    0
  309. X#define    NEWLINE    1
  310. X#define START_COMMENT    2
  311. X#define END_COMMENT    3
  312. X#define    MISC_CHARACTER    4
  313. X#define WHITE_SPACE    5
  314. X
  315. Xtypedef char    Bool;
  316. X#define True    1
  317. X#define False    0
  318. X
  319. Xtypedef int    State;
  320. X#define    Code    0
  321. X#define Comment    1
  322. X#define Quiescent    2
  323. X
  324. X#define FNULL    ( (FILE *) 0)
  325. X#define CNULL    ( (char *) 0)
  326. X
  327. XBool    only_stdin = False;        /* true if reading from stdin */
  328. X
  329. Xmain(argc, argv)
  330. X    int    argc;
  331. X    char    *argv[];
  332. X{
  333. X    Token    GetChar();
  334. X    FILE    *nextfp();
  335. X    register Token    input;
  336. X    register State    statevar = Quiescent, laststate = Quiescent;
  337. X    FILE    *fp;
  338. X    char    *filename;
  339. X    int    filecount = 0;
  340. X    long    cod_linect, com_linect, blnk_linect, comment_ct;
  341. X    long    tot_cdline, tot_cmline, tot_bkline, tot_comment;
  342. X    Bool    following_com = False;
  343. X
  344. SHAR_EOF
  345. echo "End of part 8"
  346. echo "File src/kdsi/kdsi.c is continued in part 9"
  347. echo "9" > s2_seq_.tmp
  348. exit 0
  349.  
  350.  
  351.