[net.sources] listc.c -- list C source code

mikec@reed.UUCP (Michael Cooper) (11/23/84)

[ This line is defective. ]

listc is a program to list C source code in a formated manner.  See the
manual for more detailed info.

					Michael Cooper
					tektronix!reed!mikec

#----------C--U--T-----H--E--R--E---------------C--U--T-------H--E--R--E-------
# 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.)
#
# Date Created: Thu Nov 22 21:10:49 PST 1984
# Contents of archive:
# Makefile README listc.1 listc.c
echo x - listc.1
sed 's/^x//' >listc.1 <<'!Funky!Stuff!'
x.TH LISTC 1 
x.SH NAME
xlistc \- list C source code
x.SH SYNOPSIS
x.B listc 
x[ 
x.B \-h 
x.UL 
xheader
x.B \-i# 
x.B \-l 
x.B \-L 
x.B \-f
x.B \-e 
x] 
x.B file1 
x.B file2 ... 
x.B filen
x.br
x.SH DESCRIPTION
x.I listc
xprints a listing of C source code using line numbering and level
xtracking.  
xIt is based on a version originally written in Whitesmith's
xC and then converted to run under standard C.  
xThis version is not derived from the original.  
xOnly the basic format is.  
xUnlike the original, though,
xit currently does not support a cross referencing option.  This
xmay be a while.
x.PP
xThe following options are currently supported:
x.TP 10
x.B "l"		
xTurn off the line numbering.
x.TP 10
x.B "L"		
xTurn off the level tracking.
x.TP 10
x.B "i#"		
xIndent # spaces before every line.
x.TP 10
x.B "h header"	
xPlace header in place of the file name.
x.TP 10
x.B "f"
xUse newlines instead of formfeeds.
x.TP 10
x.B "e"		
xEnhance the braces [ {} ] in a file.
x.br
x.sp 1
x.SH "SEE ALSO"
xpr(1)
x.sp 1
x.SH DIAGNOSTICS
xThere are no diagnostics.
x.sp 1
x.SH AUTHOR
xMichael Cooper (tektronix!reed!mikec)
!Funky!Stuff!
echo x - Makefile
cat >Makefile <<'!Funky!Stuff!'
#
# Makefile for listc
#
# 11-22-84	reed!mikec
#

CC = cc
CFLAGS = -O -s
# destination directory
BIN = /bin
# put in a define for HELP if you want a help summary printed along
# with a usage message.  Just a usage message is printed if this is not
# defined.
DEFS=

listc: listc.c
	${CC} ${CFLAGS} listc.c -o listc


install: listc 
	mv listc ${BIN}

man: listc.1
	nroff -man listc.1 > listc.man

all: listc man
!Funky!Stuff!
echo x - README
cat >README <<'!Funky!Stuff!'
11-22-84						Michael Cooper

This directory contains the source to listc.  To compile it, just
type 'make'.  Look at Makefile for local dependancies. 

Please send comments/changes/fixes to:

{decvax, ucbvax, pur-ee, uw-beaver, masscomp, cbosg,
 mit-ems, psu-cs, uoregon, orstcs, ihnp4, uf-cgrl}!tektronix
						      \
						       +---!reed!mikec
{teneron, ogcvax, muddcs, cadic, oresoft, grpwre,     /
 				 isonvax, nsc-pdc}---+
!Funky!Stuff!
echo x - listc.c
cat >listc.c <<'!Funky!Stuff!'
/*
**
**	LISTC:		Make nice listings of C source files.
**
**  options:
**
**	-l		turn off line numbering.
**	-L		turn off level tracking.
**	-i#		indent # spaces before every line.
**	-h header	place header in place of the file name.
**	-f		turn off formfeeds and use '\n'.
**	-e		enhance the braces in a file ({}).
**
**  usage: listc [-h header -i# -l -L -f -e] file1 file2 ... filen
**
**
**	Michael Cooper
**	tektronix!reed!mikec
**
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>

#define MAXLINE 135
#define PAGESIZE 54

int     linenum,
        level,
        pagenum,
        inum,
        hflag,
        iflag,
        Lflag,
        eflag,
        fflag,
        lflag;

char    line[MAXLINE],
       *sheader;
char   *ctime ();


FILE * fp;

main (argc, argv)
int     argc;
char   *argv[];
{
	int     lines,
	        x,
	        i;
	hflag = inum = x = eflag = fflag = Lflag = iflag = lflag = 0;

	if (argc == 1)
		help ();

	for(x=1; x<argc; x++) {
		if(argv[x][0] != '-')
			break;
		
		switch (argv[x][1]) {

			case 'i': 
				iflag = 1;
				inum = atoi (&argv[x][2]);
				break;

			case 'h': 
				sheader = argv[++x];
				hflag = 1;
				break;

			case 'f': 
			case 'D': 
				fflag = 1;
				break;

			case 'L': 
				Lflag = 1;
				break;

			case 'l': 
				lflag = 1;
				break;

			case 'e': 
				eflag = 1;
				break;

			default: 
				usage ();
				exit(0);
		}
	}
	argc -= (x - 1);
	argv += (x - 1);


	while (--argc) {
		lines = linenum = pagenum = level = 0;
		if ((fp = fopen (*++argv, "r")) == NULL) {
			fprintf (stderr, "listc: can't access %s\n", *argv);
			exit (0);
		}

		++pagenum;
		if (iflag)
			indent ();

		header (*argv);

		while (fgets (line, MAXLINE, fp) != NULL) {
			if (lines++ == PAGESIZE) {
				lines = 0;
				++pagenum;
				if (fflag)
					dumb ();
				else
					putchar ('\f');
				header (*argv);
			}
			++linenum;
			split ();
		}
		fclose (fp);
		if (fflag)
			dumb ();
		else
			putchar ('\f');
	}
	if (fflag)
		dumb ();
	else
		putchar ('\f');
}


header (filename)
char   *filename;
{
	int     i;
	struct stat     sbuf;

	long int        t;
	char   *itoa ();
	char   *foo;
	char    s;
	char    tbuf;

	putchar ('\n');

	time (&t);

	if (iflag)
		indent ();
	if (hflag)
		printf ("  %.*s\t%s\t\t\t\t\t\t PAGE %d\n\n",
				24 - 5, (char *) ctime (&t), sheader, pagenum);
	else
		printf ("  %.*s\t%s\t\t\t\t\t\t PAGE %d\n\n",
				24 - 5, (char *) ctime (&t), filename, pagenum);
	if (iflag)
		indent ();
	if (lflag) {
		if (Lflag)
			printf ("\t\t\t\tSOURCE STATEMENT\n\n");
		else
			printf ("\tLEVEL\t\t\tSOURCE STATEMENT\n\n");
	}
	else
		if (!lflag && Lflag)
			printf ("\tLINE      \t\tSOURCE STATEMENT\n\n");
		else
			printf ("\tLINE   LEVEL\t\tSOURCE STATEMENT\n\n");
}

split () 
{
	int     i,
	        x;
	char    c,
	       *o,
	        s[MAXLINE + 20],
	       *list;
	o = line;
	if (iflag)
		indent ();
	if (lflag) {
		if (Lflag)
			printf ("\t\t");
		else {
			if (level)
				printf ("\t%d\t", level);
			else
				printf ("\t\t");
		}
	}
	else
		if (!lflag && Lflag)
			printf ("\t%d\t", linenum);
		else {
			printf ("\t%d", linenum);
			if (level)
				printf ("\t%d", level);
			else
				printf ("\t");

		}

	x = 0;
	while ((c = *o++) != '\0')
		switch (c) {
			case '{': 
				++level;
				if (eflag) {
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
				}
				else
					s[x++] = c;
				break;

			case '}': 
				--level;
				if (eflag) {
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
					s[x++] = c;
					s[x++] = '\b';
				}
				else
					s[x++] = c;
				break;

			default: 
				s[x++] = c;
				break;

		}
	s[x++] = '\0';
	list = s;
	printf ("\t%s", list);
}

dumb () 
{
	int     i;

	for (i = 0; i < 4; ++i);
	putchar ('\n');

}

indent () 
{

	int     i;

	for (i = 0; i < inum; ++i)
		putchar (' ');

}


help () 
{
#ifdef HELP
	printf ("\tLISTC:\tMake nice listings of C source files.\n\n");
#endif
	usage ();
#ifdef HELP
	printf ("\noptions:\n");
	printf ("\t-l\t\tturn off the line numbering.\n");
	printf ("\t-L\t\tturn off the level tracking.\n");
	printf ("\t-i#\t\tindent # spaces before every line.\n");
	printf ("\t-h header\tplace header in place of the file name.\n");
	printf ("\t-f\t\tuse '\n' instead of formfeeds.\n");
	printf ("\t-e\t\tenhance the braces [ {} ] in a file.\n");
#endif
	exit (0);
}

usage ()
{
	printf ("usage: listc [ -h header -i# -l -L -D -e ] file1 file2 ... filen\n");
}
!Funky!Stuff!