jhhur@kaist.UUCP (Hur, Jinho) (01/21/85)
Since there has been a lot of request to post whole source of C style program. Cut on the line below, and feed to sh. ============================================================================== # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # Makefile style style.cnt.awk style.com.sed style.detab.c style.dict style.met.awk style.stan.c style.str.sed echo x - Makefile cat > "Makefile" << '//E*O*F Makefile//' all: style.detab style.stan style.detab: style.detab.c cc -o style.detab style.detab.c style.stan: style.stan.c cc -o style.stan style.stan.c //E*O*F Makefile// echo x - style cat > "style" << '//E*O*F style//' TMP1=/tmp/style1$$ TMP2=/tmp/style2$$ RESULTS=/tmp/stat$$ LIB=. trap "rm -f $TMP1 $TMP2 $RESULTS; trap ''0; exit" 0 1 2 13 15 for i do echo; echo 'Style analysis of ' $i if test -r $i then : --- count comment lines and total lines. awk -f $LIB/style.cnt.awk $i > $RESULTS : : --- replace tabs by spaces : --- convert to lower case : --- fix strings and comment delimiters : --- remove comments : $LIB/style.detab < $i |\ tr "[A-Z]" "[a-z]" |\ sed -f $LIB/style.str.sed |\ sed -n -f $LIB/style.com.sed > $TMP1 : : --- sort program words : tr -cs "a-z0-9_" "\012" < $TMP1 |\ sed -n '/^[a-z]/p' |\ sort -u > $TMP2 : : --- find length of user identifiers. : comm -23 $TMP2 $LIB/style.dict |\ awk >> $RESULTS \ '{totl += length}; \ END {print "NL ";\ if (NR) print (totl/NR); else print 0;\ print "ID " NR }' : : --- count variety of reserved woeds : comm -12 $TMP2 $LIB/style.dict |\ (echo "RW" `wc -l`) >> $RESULTS : : --- produce remaining metrics : awk -f $LIB/style.met.awk $TMP1 >> $RESULTS : : --- and analyse : $LIB/style.stan < $RESULTS else echo " Cannot read"; echo "" fi done //E*O*F style// echo x - style.cnt.awk cat > "style.cnt.awk" << '//E*O*F style.cnt.awk//' # count commented lines { if (index ($0, "/*") || index($0, "*/")) comments++ } # count preprocessor lines /^#include/ { includes++ } /^#define/ { defines++ } # report include files, defines, commented lines & total lines END { print "IF " (includes+0) print "DF " (defines+0) print "CL " (comments+0) print "TL " (NR+0) } //E*O*F style.cnt.awk// echo x - style.com.sed cat > "style.com.sed" << '//E*O*F style.com.sed//' s/ Decomment a C program /&/ :start s/ Strip trailing spaces /&/ /[ ]*$/ s/[ ]*$// s/ Lose comment-only lines /&/ /^[ ]*@.*`$/ d s/ Strip short comments /&/ /@.*`/ s/@[^@]*`//g s/ Strip multiple comments /&/ /^[ ]*@.*$/ b loop /@.*$/ { s/[ ]*@.*$//p :loop n s/ Ensure flag is reset /&/ t dummy :dummy s/ Go on until delimiter /&/ s/^[^@]*`// /^[ ]*$/ d t start b loop } s/ Print whatever's left /&/ p //E*O*F style.com.sed// echo x - style.detab.c cat > "style.detab.c" << '//E*O*F style.detab.c//' /******************************************************************* * Detab - converrts tabs to appropriate number of spaces * ( transcribed from Kernighan & Plauger's Software tools. ******************************************************************* */ #include <stdio.h> #define MAXLINE 132 main() { int c, i, tabs[MAXLINE], col=1; set_tabs (tabs); while (( c = getchar()) != EOF ) if ( c== '\t' ) do {putchar (' '); col++;} while ( !tab_pos (col, tabs)); else if ( c== '\n' ) {putchar( '\n' ); col = 1;} else {putchar( c ); col++; } } /* set up tab positions */ set_tabs( tabs ) int tabs[MAXLINE]; { int i; for ( i = 1; i <= MAXLINE; i++ ) tabs[i] = (( i % 8) == 1 ? 1: 0); } /* see if we are at a tab position */ tab_pos( col, tabs ) int col, tabs[MAXLINE]; { return (( col > MAXLINE ) ? 1 : tabs[col] ); } //E*O*F style.detab.c// echo x - style.dict cat > "style.dict" << '//E*O*F style.dict//' alloc argc argv auto break case char close continue default do double else entry eof extern fclose fdopen feof ferror fgets file float fopen for fprintf fputs freopen fscanf ftell getc getchar goto if int long null printf putc putchar registerstruct return scanf short sizeof sprintf sscanf static stderr stdin stdout switch typedef union unsigned while //E*O*F style.dict// echo x - style.met.awk cat > "style.met.awk" << '//E*O*F style.met.awk//' # Produce "style" metrics for a C program # Compute number of blank lines { if (NF==0) { blank++; next }} # Compute number of nunblank characters and embedded spaces { nbchars = 0 for ( i = NF; i > 0; i-- ) nbchars += length($i) nonblank += nbchars start = index ($0, $1) embedded += length - nbchars - ( start - 1) } # Compute amount of indentation /^[ ]/ { indented += index($0,$1) -1 } # Compute total number of characters { chars += length } # Compute number of modules /^[a-z_][a-z_0-9]*[ a-z_0-9]*\(.*\)/ { module++ } # Compute number of goto's /^goto[ ]+|[ ]+goto[ ]+/ { jumps++ } # Report results END { print "NR " (NR+0) print "LC " (NR-blank) print "NB " (nonblank+0) print "IN " (indented+0) print "TC " (chars+0) print "BL " (blank+0) print "IM " (embedded+0) print "MO " (module+0) print "JU " (jumps+0) } //E*O*F style.met.awk// echo x - style.stan.c cat > "style.stan.c" << '//E*O*F style.stan.c//' /************************/ /* Analys style metrics */ /************************/ #define PARAMS 11 main() { static int max[] = { 9, 12, 12, 11, 8, 15, 6, 14, -20, 5, 8}, /* ch cl in bl sp ml rw id go if df */ L[] = { 8, 8, 8, 8, 1, 4, 4, 4, 1, 0, 10 }, S[] = { 12, 15, 24, 15, 4, 10, 16, 5, 3, 3, 15 }, F[] = { 25, 25, 48, 30, 10, 25, 30, 10, 199, 3, 25 }, H[] = { 30, 35, 60, 35, 12, 35, 36, 14, 200, 4, 30}; float param[PARAMS]; static char *ident[] = { " chars per line ", /* ch */ "% comment lines ", /* cl */ "% indentation ", /* in */ "% blank lines ", /* bl */ " spaces per line ", /* sp */ " module length ", /* ml */ " reserved words ", /* rw */ " identifier length ", /* id */ " goto's ", /* go */ " include files ", /* if */ "% define's " }; /* df */ int i; float blank, non_blank, comments, includes, defines, indented, embedded, modules, jumps, ids, name_length, score, old_score, fact, total_chars, word_count, line_count, total_lines, lines, f; char s[8]; /* Read in the metrics. */ for ( i = 0; i < 16; i++ ) { scanf ( "%s %f", s, &f ); if ( strcmp(s, "IF") == 0) includes = f; else if ( strcmp(s, "DF") == 0) defines = f; else if ( strcmp(s, "NR") == 0) lines = f; else if ( strcmp(s, "NL") == 0) name_length = f; else if ( strcmp(s, "ID") == 0) ids = f; else if ( strcmp(s, "RW") == 0) word_count = f; else if ( strcmp(s, "CL") == 0) comments = f; else if ( strcmp(s, "TL") == 0) total_lines = f; else if ( strcmp(s, "LC") == 0) line_count = f; else if ( strcmp(s, "NB") == 0) non_blank = f; else if ( strcmp(s, "IN") == 0) indented = f; else if ( strcmp(s, "TC") == 0) total_chars = f; else if ( strcmp(s, "BL") == 0) blank = f; else if ( strcmp(s, "IM") == 0) embedded = f; else if ( strcmp(s, "MO") == 0) modules = f; else if ( strcmp(s, "JU") == 0) jumps = f; } /* Perform Analysis */ line_count = lines - blank; if (line_count) non_blank /= line_count; if (total_lines) comments /= total_lines / 100; if (total_chars) indented /= total_chars / 100; if (lines) blank /= lines / 100; if (line_count) embedded /= line_count; if (modules) modules = line_count / modules; if (ids) defines /= ids / 100; param[0] = non_blank; param[1] = comments; param[2] = indented; param[3] = blank; param[4] = embedded; param[5] = modules; param[6] = word_count; param[7] = name_length; param[8] = jumps; param[9] = includes; param[10] = defines; old_score = 0; for ( i = 0; i < PARAMS; i++ ) { if( S[i] <= param[i] && param[i] <= F[i] ) score += max[i]; else if ( L[i] <= param[i] && param[i] < S[i] ) { fact = (param[i] - L[i]) / (S[i] - L[i]); score += max[i] * fact; } else if ( F[i] < param[i] && param[i] <= H[i]) { fact = ( H[i] - param[i] ) / ( H[i] - F[i] ); score += max[i] * fact; } printf("\n%5.1f%s : %5.1f\t(max %3d)", param[i], ident[i], score-old_score, max[i]); old_score = score; } printf("\n\nScore %5.1f\n",score); } //E*O*F style.stan.c// echo x - style.str.sed cat > "style.str.sed" << '//E*O*F style.str.sed//' s/ Takes strings out of a C program /&/ s/ and replace comment delimiter /&/ s/ by single character /&/ s/ Remove quoted characters ... /&/ s/'[^']*'//g s/ ... and quoted strings /&/ s/"[^"]*"//g s/ Replace comment delimiters /&/ s/\/\*/@/g s/\*\//`/g //E*O*F style.str.sed// exit 0 -- real: Hur, Jinho Dept of Computer Science, KAIST uucp: ..!hplabs!kaist!jhhur csnet: jhhur%kaist@csnet-relay.csnet