[net.sources] C style program sources

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