[comp.lang.smalltalk] stLgrind - fileOut files to LaTeX

barad@brand.UUCP (Herb Barad) (05/01/87)

After MANY requests for stLgrind, I am submitting this to the net.  I
am submitting this directly to this newsgroup (instead of net.sources)
since many of the readers of this group do not read net.sources (and
even indicated this in their requests).  Also, many net.sources
readers could care less about Smalltalk or LaTeX.

This is stLgrind.  This is a tool that will convert Smalltalk-80 
fileOut files into LaTeX files.  Please report any bugs to me.  Note
that you might have to rebuild LaTeX to extend some of the parameters
(such as save_size) if your methods become too large with too many
levels of indentation.  I mention this in the manual page.

This program is a hacked-up version of stgrind (a Berkeley tool to
convert fileOut into troff).  I plan future enhancements, but don't
hold your breath. (as I need to graduate some day...)

				Herb Barad

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	Makefile
#	stLgrind.1
#	stLgrind.c
# This archive created: Fri Apr 17 16:01:47 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(685 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^	X//' << \SHAR_EOF > 'README'
	XThis is stLgrind.  This tool is very useful to create LaTeX formatted
	Xversions of Smalltalk-80 source code.  The Smalltalk-80 source comes
	Xfrom the fileOut command.
	X
	XBeside the Berkeley Smalltalk project (whose stgrind program was used
	Xas a skeleton for stLgrind), I would like to thank Ralph Johnson
	X(johnson@p.cs.uiuc.edu) for some suggestions and fixes.
	X
	XGood Luck.
	X
	XHerb Barad	[USC - Signal and Image Processing Institute]
	X
	XUSENET:		...!sdcrdcf!usc-oberon!brand!barad			or
	X		...!mcvax!seismo!sdcsvax!sdcrdcf!usc-oberon!brand!barad
	X
	XARPANET:	barad@brand.usc.edu
	X
	XUSMail:		Univ. of Southern California
	X		Powell Hall 306, MC-0272
	X		Los Angeles, CA 90089-0272
	X		phone: (213) 743-0911
	X
SHAR_EOF
if test 685 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 685 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(257 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile'
	X#Use -g flag for debugging
	XCFLAGS = -O -s
	X#CFLAGS = -g
	XBIN = /usr/local/bin
	XMAN = /usr/local/man/man1
	X
	XstLgrind: stLgrind.c
	X	cc $(CFLAGS) -o stLgrind stLgrind.c
	X
	Xinstall: stLgrind stLgrind.1
	X	cp stLgrind $(BIN)
	X	cp stLgrind.1 $(MAN)
	X
	Xclean:
	X	rm -f stLgrind
SHAR_EOF
if test 257 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 257 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'stLgrind.1'" '(1330 characters)'
if test -f 'stLgrind.1'
then
	echo shar: will not over-write existing file "'stLgrind.1'"
else
sed 's/^	X//' << \SHAR_EOF > 'stLgrind.1'
	X.\" $Header: stLgrind.1,v 1.1 87/04/17 15:57:33 barad Stab $
	X.TH stLgrind 1
	X.SH NAME
	XstLgrind - convert fileOut formatted files into LaTeX source files
	X.SH SYNOPSIS
	X.B stLgrind filename.st > filename.tex
	X.SH DESCRIPTION
	XThis program will convert files created by the fileOut command of
	XSmalltalk-80 into files suitable for LaTeX processing.  The input
	Xfilename is given on the command line as the only argument.  The
	Xoutput LaTeX code is sent to the standard output.
	X
	XThis program is similar to the stgrind program that was created for
	XBerkeley Smalltalk.  The program stgrind would create troff output
	Xfrom a fileOut file.
	X.SH AUTHOR
	X.br
	XHerb Barad
	X.br
	XUSC Signal and Image Processing Inst.
	X.br
	XPHE 306; MC-0272
	X.br
	XLos Angeles, CA 90089-0272
	X.br
	X
	X.br
	Xbarad@brand.usc.edu
	X.SH BUGS
	XThe files produced by this program can sometimes exceed the default
	Xcapacity for TeX (and LaTeX).  If needed, you will have to remake tex
	Xand latex with the parameter save_size increased.  As distributed, it
	Xis set to 600.  The maximum value that this may take on is equal to
	Xthe largest integer you can make from half a word size.  For example,
	Xa 32-bit machine has a halfword size of 16 bits.  The maximum value
	Xfor save_size can therefore be 65535.  A value of 6000 is usually
	Xplenty large.
	X.br
	XOnly handles a finite amount of tabbing per line.
SHAR_EOF
if test 1330 -ne "`wc -c < 'stLgrind.1'`"
then
	echo shar: error transmitting "'stLgrind.1'" '(should have been 1330 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'stLgrind.c'" '(14342 characters)'
if test -f 'stLgrind.c'
then
	echo shar: will not over-write existing file "'stLgrind.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'stLgrind.c'
	Xstatic char rcsId[] = "$Header: stLgrind.c,v 1.6 87/04/17 15:47:24 barad Stab $";
	X
	X/*
	X *	stLgrind -- converts Smalltalk ``fileOut'' files to LaTeX format
	X *
	X *	Herb Barad	[USC - Signal and Image Processing Institute]
	X *
	X * USENET:	...!sdcrdcf!usc-oberon!brand!barad	      or
	X *		...!mcvax!seismo!sdcsvax!sdcrdcf!usc-oberon!brand!barad
	X *
	X * ARPANET:	barad%brand.usc.edu
	X *
	X * USMail:		Univ. of Southern California
	X *		Powell Hall 306, MC-0272
	X *		Los Angeles, CA 90089-0272
	X *		phone: (213) 743-0911
	X *	
	X *
	X * with lots of help from Ralph Johnson
	X *		johnson@p.cs.uiuc.edu
	X *
	X *	Usage: stLgrind file.st > file.tex ; latex file
	X *
	X * NOTE: much of this codes comes from stgrind, a tool from the Berkeley
	X * Smalltalk project.
	X */
	X
	X# include	<stdio.h>
	X# include	<ctype.h>
	X
	X# define	FALSE		0
	X# define	TRUE		(~FALSE)
	X
	Xchar	filename[BUFSIZ];	/* current input file name */
	XFILE	*infp;
	X
	Xtypedef int	boolean;
	X
	X# define	EXPRLEN		10000
	Xchar	buf[EXPRLEN];		/* stores fileOut expressions */
	Xint	bp;
	X
	Xboolean	isTimeStamp(), isComment(), isDefinition(), isClassDefinition(),
	X	isClassComment(), isMethodsFor(), isDoIt(),
	X	getNextExpr(), checkWord();
	X
	Xint	bufIndex();
	X
	Xvoid	scanTimeStamp(), scanComment(), scanDefinition(), scanClassComment(),
	X	scanClassDefinition(), scanMethodsFor(), scanMethod(), scanDoIt(),
	X	extractWord(), fatal(), getargs();
	X
	Xchar	*date();
	X
	X
	Xmain(argc, argv)
	Xint argc;
	Xchar **argv;
	X{
	X	getargs(argc, argv);
	X
	X	printf("\\documentstyle{article}\n");
	X	printf("\\if@twoside\n\\oddsidemargin 34pt\n\\evensidemargin 72pt\n");
	X	printf("\\textheight 600pt\n\\topmargin 0pt\n");
	X	printf("\\marginparwidth 97pt\n\\else\\oddsidemargin 30 pt\n");
	X	printf("\\evensidemargin 30 pt\n\\marginparwidth 80pt\n\\fi\n");
	X	printf("\\textwidth 400 pt\n");
	X	printf("\\parindent 0pt\n\n");
	X	printf("\\pagestyle{myheadings}\n");
	X	printf("\\begin{document}\n");
	X	printf("\\markright{Listing from {\\it %s\\/} at {\\it %s\\/}}\n",
	X	       filename, date());
	X	printf("\\thispagestyle{empty}"); 
	X
	X	while (getNextExpr(infp)) {
	X		if (isTimeStamp())
	X			scanTimeStamp();
	X		else if (isComment())
	X			scanComment();
	X		else if (isClassComment())
	X			scanClassComment();
	X		else if (isClassDefinition())
	X			scanClassDefinition();
	X		else if (isDefinition())
	X			scanDefinition();
	X		else if (isMethodsFor())
	X			scanMethodsFor();
	X		else if (isDoIt())
	X			scanDoIt();
	X		else 
	X			scanMethod();
	X	}
	X	printf("\n\\end{document}\n");
	X}
	X
	X
	X/*
	X *	Finite state machine to read an expression at a time.
	X *	An expression is
	X *		!string!
	X *		string!
	X *		string! !
	X *	where string may contain carriage returns.  Could have used
	X *	lex, but the carriage returns will be nasty.
	X *	Returns TRUE if an expression has been read successfully.
	X *	Returns FALSE on eof.
	X *	Expression read is stored in the global variable "buf".
	X *	Doesn't check for buffer overflow.
	X */
	X
	Xboolean
	XgetNextExpr(fp)
	XFILE *fp;
	X{
	X	register char	ch;
	X	register int	state;
	X
	X	/*
	X	 *	State names for FSM scanner
	X	 */
	X
	X#	define	ST_START	0
	X#	define	ST_1		1
	X#	define	ST_2		2
	X#	define	ST_3		3
	X#	define	ST_4		4
	X#	define	ST_STOP		99999
	X
	X#	define	getNextChar(ch, fp)\
	X		if ((ch = getc(fp)) == EOF)\
	X			return(FALSE);\
	X		else
	X
	X			
	X	while ((ch = getc(fp)) != EOF)		/* skip all blanks */
	X		if (ch == EOF)
	X			return(FALSE);
	X		else if (!isspace(ch))
	X			break;
	X		
	X	bp = 0;
	X	state = ST_START;
	X	
	X	while (state != ST_STOP) {
	X		switch (state) {
	X		case ST_START:
	X			buf[bp++] = ch;
	X			state =  ch == '!'  ?  ST_1  :  ST_2;
	X			getNextChar(ch, fp);
	X			break;
	X		case ST_1:
	X			buf[bp++] = ch;
	X			if (ch == '!')
	X				state = ST_STOP;
	X			else
	X				getNextChar(ch, fp);
	X			break;
	X		case ST_2:
	X			buf[bp++] = ch;
	X			if (ch == '!')
	X				state = ST_3;
	X			getNextChar(ch, fp);
	X			break;
	X		case ST_3:
	X			if (ch == '!') {
	X				state = ST_2;
	X				getNextChar(ch, fp);
	X			}
	X			else if (ch == ' ') {
	X				state = ST_4;
	X				getNextChar(ch, fp);
	X			}
	X			else {
	X				state = ST_STOP;
	X				ungetc(ch, fp);
	X			}
	X			break;
	X		case ST_4:
	X			if (ch == '!') {
	X				buf[bp++] = ' ';
	X				buf[bp++] = '!';
	X			}
	X			else
	X				ungetc(ch, fp);
	X			state = ST_STOP;
	X			break;
	X		default:
	X			fatal("getNextExpr: unknown state: %d", state);
	X			break;
	X		}
	X	}
	X	buf[bp] = '\0';
	X	return(TRUE);
	X}
	X
	X
	X/*
	X *	Reports fatal error and die.
	X */
	X
	Xvoid
	Xfatal(fmt, s1, s2, s3, s4)
	Xchar *fmt;
	Xint s1, s2, s3, s4;
	X{
	X	char	strbuf[BUFSIZ];
	X
	X	sprintf(strbuf, fmt, s1, s2, s3, s4);
	X	fprintf(stderr, "%s\n", strbuf);
	X	exit(1);
	X}
	X
	X
	X/*
	X *	The following messages classifies a fileOut expression using
	X *	various heuristics.  Returns TRUE if the expression in "buf"
	X *	is of a given type.
	X */
	X
	X/*
	X *	Detects doIt's (e.g. Class initialize!)
	X */
	X
	Xboolean
	XisDoIt()
	X{
	X	return(isupper(*buf)  &&  buf[bp - 2] != ' '
	X	    &&  buf[bp - 1] == '!');
	X}
	X
	X
	X/*
	X *	Detects the time stamp, which looks like
	X *		'date and version'!
	X *	from Smalltalk.  Not always correct.
	X */
	X
	Xboolean
	XisTimeStamp()
	X{
	X	return(*buf == '\'');
	X}
	X
	X
	X/*
	X *	Detects a comment.  ("....."!)
	X */
	X
	Xboolean
	XisComment()
	X{
	X	return(*buf == '"');
	X}
	X
	X
	X/*
	X *	Detects the definition of a new class.
	X */
	X
	Xboolean
	XisDefinition()
	X{
	X	return(checkWord(2, "subclass:")
	X	    ||  checkWord(2, "variableSubclass:")
	X	    ||  checkWord(2, "variableByteSubclass:")
	X	    ||  checkWord(2, "variableWordSubclass:"));
	X}
	X
	X
	X/*
	X *	Detects this,
	X *		Date comment: 'This is a comment'!
	X */
	X
	Xboolean
	XisClassComment()
	X{
	X	return(checkWord(2, "comment:"));
	X}
	X
	X
	X/*
	X *	!Class methodsFor: 'controlling'!
	X */
	X
	Xboolean
	XisMethodsFor()
	X{
	X	return(*buf == '!');
	X}
	X
	X
	X/*
	X *	Definition of a class.
	X *		Class class instanceVariables: ''....!
	X */
	X
	Xboolean
	XisClassDefinition()
	X{
	X	return(checkWord(2, "class")
	X	    &&  checkWord(3, "instanceVariableNames:"));
	X}
	X
	X
	X
	X/*
	X *	The following messages looks at the contents of "buf",
	X *	decodes it, and outputs the contents.
	X */
	X
	Xvoid
	XscanDoIt()
	X{
	X	register int	i;
	X
	X	for (i = 0;  buf[i] != '!';  i++)
	X		putchar(buf[i]);
	X	printf(" {\\bf doIt}\n");
	X}
	X
	X
	Xvoid
	XscanClassDefinition()
	X{
	X	int	i;
	X
	X	printf("\n\\begin{verbatim}\n");
	X	for (i = 0;  buf[i] != '!';  i++)
	X		putchar(buf[i]);
	X	printf("\n\\end{verbatim}\n");
	X}
	X
	X
	Xvoid
	XscanTimeStamp()
	X{
	X	register int	i;
	X
	X	printf("\n\\markright{\\it ");
	X	i = 1;
	X	while (buf[i] != '\'')
	X		putchar(buf[i++]);
	X	printf("}");
	X}
	X
	X
	Xvoid
	XscanComment()
	X{
	X	register int	i, line_length;
	X
	X	line_length = 0;
	X	printf("{\\it ");
	X	for (i = 0;  buf[i] != '!';  line_length++,i++)
	X	  switch (buf[i]){
	X	  case ' ':
	X	    if (line_length < 200) putchar(buf[i]); /* prevent long lines */
	X	    else {putchar('\n'); line_length = 0;}
	X	    break;
	X	  case '#':
	X	    printf("\\#");
	X	    break;
	X	  case '$':
	X	    printf("\\$");
	X	    break;
	X	  case '&':
	X	    printf("\\&");
	X	    break;
	X	  case '%':
	X	    printf("\\%");
	X	    break;
	X	  case '{':
	X	    printf("\\{");
	X	    break;
	X	  case '}':
	X	    printf("\\}");
	X	    break;
	X	  case '<':
	X	    printf(" $<$ ");
	X	    break;
	X	  case '>':
	X	    printf(" $>$ ");
	X	    break;
	X	  default:
	X	    putchar(buf[i]);
	X	    break;
	X	  }
	X	printf("}\n");
	X}
	X
	X
	Xvoid
	XscanDefinition()
	X{
	X	char	word[100];
	X	int	wordIndex;
	X#	define	W_SUPERCLASS		1
	X#	define	W_CLASS			3
	X#	define	W_INSTVAR		5
	X	
	X	extractWord(W_CLASS, word);
	X	printf("\n\\markright{\\bf %s}\n", word);
	X	printf("\\vskip 0.2in\n");
	X	printf("\\begin{center}\n{\\LARGE \\bf %s}\n\\end{center}\n", word);
	X	printf("\\hskip 3in\n");
	X
	X	printf("\\begin{tabbing}\n");
	X	printf("instance variable names (set tabs out here) \\=\\kill\n");
	X	printf("class name\\> {\\bf %s}\\\\ \n", word);
	X
	X	extractWord(W_SUPERCLASS, word);
	X	printf("superclass\\> {\\bf %s}\\\\ \n", word);
	X
	X	wordIndex = W_INSTVAR;
	X	if (checkWord(W_INSTVAR, "classVariableNames:"))
	X	  printf("instance variable names\\> {\\it none}\\\\ \n");
	X	else {
	X		extractWord(W_INSTVAR, word);
	X		printf("instance variable names \\> {\\bf %s}\\\\ \n", word);
	X		wordIndex++;
	X		while (!checkWord(wordIndex, "classVariableNames:")) {
	X			extractWord(wordIndex++, word);
	X			printf("\\> {\\bf %s}\\\\ \n", word);
	X	        }
	X	}
	X	
	X	wordIndex++;
	X	if (checkWord(wordIndex, "poolDictionaries:"))
	X	  printf("class variable names\\> {\\it none}\\\\ \n");
	X	else {
	X		extractWord(wordIndex++, word);
	X		printf("class variable names\\> {\\bf %s}\\\\ \n", word);
	X		while (!checkWord(wordIndex, "poolDictionaries:")) {
	X			extractWord(wordIndex++, word);
	X			printf("\\> {\\bf %s}\\\\ \n", word);
	X		}
	X	}
	X	
	X	wordIndex++;
	X	if (checkWord(wordIndex, "category:"))
	X                printf("pool dictionaries\\> {\\it none}\\\\ \n");
	X	else {
	X		extractWord(wordIndex++, word);
	X		printf("pool dictionaries\\> {\\bf %s}\\\\ \n", word);
	X		while (!checkWord(wordIndex, "category:")) {
	X			extractWord(wordIndex++, word);
	X			printf("\\> {\\bf %s}\\\\ \n", word);
	X		}
	X        }
	X	
	X	extractWord(++wordIndex, word);
	X	printf("category\\> {\\bf %s}\n", word);
	X
	X        printf("\\end{tabbing}\n\n\n");
	X	/* set tabs here */
	X}
	X
	X
	X/*
	X *	returns the index of the first character in buf[] of the index'th
	X *	word.
	X */
	X
	Xint
	XbufIndex(index)
	Xint index;
	X{
	X	int	i = 0;
	X
	X	while (--index) {
	X		while (!isspace(buf[i]))
	X			i++;
	X		while (isspace(buf[i]) ||  buf[i] == '\''  ||  buf[i] == '#')
	X			i++;
	X	}
	X	return(i);
	X}
	X
	X
	X/*
	X *	returns TRUE if index'th word in buf[] matches aString.
	X */
	X
	Xboolean
	XcheckWord(index, aString)
	Xint index;
	Xchar aString[];
	X{
	X	char	word[100];
	X	
	X	extractWord(index, word);
	X	return(!strcmp(word, aString)  ?  TRUE  :  FALSE);
	X}
	X
	X
	X/*
	X *	Extracts the index'th word from buf[] and stores it as a
	X *	null terminated string in aString.
	X */
	X
	Xvoid
	XextractWord(index, aString)
	Xint index;
	Xchar aString[];
	X{
	X	int	i, j;
	X	
	X	i = bufIndex(index);
	X	j = 0;
	X	while (!isspace(buf[i])  &&  buf[i] != '\'')
	X		aString[j++] = buf[i++];
	X	aString[j] = '\0';
	X}
	X
	X
	X/*
	X *	Copies a method definition expression to the output.
	X *	Some characters must be handled differently.
	X */
	X
	Xvoid
	XscanMethod()
	X{
	X	register int		i, column;
	X	register boolean	inComment = FALSE, inString = FALSE;
	X	
	X	i = 0;
	X	while (isspace(buf[i]))
	X		i++;
	X	/* method start */
	X	printf("{\\bf\\noindent ");
	X	while (buf[i] != '\n')
	X		putchar(buf[i++]);
	X	printf("}\n");
	X
	X/*	printf("\\begin{verse}\n"); */
	X	printf("\\begin{tabbing}\n");
	X	/* set tab stops */
	X	printf("eee \\= eee \\= eee \\= eee \\= eee \\= eee \\= eee \\= eee \\= eee \\= eee \\= eee \\= eee \\= eee \\= \\kill\n");
	X	column = 0;
	X	while (buf[i] != '\0') {
	X		switch (buf[i]) {
	X		case '.': /* WHAT ARE WE DOING HERE ??? */
	X		  if (i == 0 || buf[i-1] == '\n')
	X		    printf("%c",buf[i]);
	X		  else
	X		    putchar(buf[i]);
	X		  break;
	X		case '\'':
	X			if (i == 0  ||  buf[i - 1] == '\n')
	X				printf("%c", buf[i]);
	X			else
	X				putchar(buf[i]);
	X			if (!inComment) inString = !inString;
	X			break;
	X		case '\n':
	X			if ((column != 0) && (buf[i-1] != '\n'))
	X			  printf(" \\quad\\\\{}\n");
	X			column = 0;
	X			break;
	X		case '\t':
	X		        if (!inComment)
	X			  printf(" \\> ");
	X		        else
	X			  printf(" \\> \\it ");
	X			break;
	X		case '^':
	X			printf(" $\\uparrow$ ");
	X			break;
	X		case '_':
	X			printf(" $\\leftarrow$ ");
	X			break;
	X		case '\\':
	X			printf(" $\\backslash$ ");
	X			break;
	X		case '~':
	X			printf(" $\\sim$ ");
	X			break;
	X		case '!':
	X			if (buf[i + 1] == '!') {
	X				putchar('!');
	X				i++;
	X			}
	X			break;
	X       		case '|':
	X			printf(" $|$ ");
	X			break;
	X		case '"':
	X			if (inString) {
	X			  printf("\'\'");
	X			  break;
	X			}
	X			if (inComment)
	X			        printf("\'\'\n\\rm ");
	X			else
	X			        printf("\\it ``");
	X			inComment = !inComment;
	X			break;
	X		case '#':
	X			printf("\\#");
	X			break;
	X		case '$':
	X			printf("\\$");
	X			if (buf[i+1]== '"') { i++; printf("\'\'");}
	X			else if (buf[i+1] == '\'') {i++; printf("\'");}
	X			break;
	X		case '&':
	X			printf("\\&");
	X			break;
	X		case '%':
	X			printf("\\%");
	X			break;
	X		case '{':
	X			printf("\\{");
	X			break;
	X		case '}':
	X			printf("\\}");
	X			break;
	X	        case '<':
	X			printf(" $<$ ");
	X			break;
	X		case '>':
	X			printf(" $>$ ");
	X			break;
	X		default:
	X			putchar(buf[i]);
	X			break;
	X		}
	X		i++;
	X		column++;
	X	}
	X/*	printf("\\end{verse}\n"); */
	X	printf("\\end{tabbing}\n\n\n");
	X}
	X
	X
	X/*
	X *	!<class> class methodsFor: 'class protocol name'!
	X *	!<class> methodsFor: 'protocol name'!
	X */
	X
	Xvoid
	XscanMethodsFor()
	X{
	X	register int	i;
	X#	define	M_CLASS_KW	2
	X#	define	M_PROTOCOL	3
	X
	X	if (checkWord(M_CLASS_KW, "class")) {
	X	        printf("\\vskip 0.2in\n");
	X		printf("{\\Large\\bf Class Protocols For: \n");
	X		i = bufIndex(M_PROTOCOL + 1);
	X		while (buf[i] != '\'')
	X			putchar(buf[i++]);
	X	}
	X	else {
	X		printf("\\vskip 0.2in\n");
	X		printf("{\\Large\\bf Instance Protocols For: \n");
	X		i = bufIndex(M_PROTOCOL);
	X		while(buf[i] != '\'')
	X			putchar(buf[i++]);
	X	}
	X	printf("}\n\\vskip 0.1in\n");
	X}
	X
	X
	X/*
	X *	<class> comment: 'This class has no comment.'!
	X */
	X
	Xvoid
	XscanClassComment()
	X{
	X	register int	i, line_length;
	X#	define	COMMENT_START	3
	X
	X	printf("comment\n\\begin{quotation}\n{\\it ");
	X	i = bufIndex(COMMENT_START);
	X	for (line_length=0;;line_length++) {
	X		if (buf[i] == '\'') {
	X			if (buf[i + 1] == '\'')		/* ... '' ... */
	X				putchar('\'');
	X			else if (buf[i + 1] == '!')	/* ... .'! */
	X				break;
	X			else				/* ... ' ... */
	X				putchar(buf[i]);
	X		}
	X		else if (buf[i] == '!')			/* ... .! */
	X			break;
	X		else if (buf[i] == '\\')
	X		        printf("\\");
	X		else if (buf[i] == '\t') {
	X			if (i != 0  &&  buf[i - 1] == '\n')
	X				printf("\n\t");
	X			else
	X				putchar('\t');
	X		}
	X		else if (buf[i] == '#')
	X			printf("\\#");
	X		else if (buf[i] == ' ') {
	X		  if (line_length < 200) putchar(buf[i]); /* prevent long lines */
	X		  else {putchar('\n'); line_length=0;}
	X		}
	X		else
	X			putchar(buf[i]);
	X		i++;
	X	}
	X	printf("}\n\\end{quotation}\n");
	X}
	X
	X
	Xvoid
	Xgetargs(argc, argv)
	Xint argc;
	Xchar **argv;
	X{
	X	register char	*ch;
	X
	X	while (--argc > 0 && (*++argv)[0] == '-')
	X		for (ch=argv[0]+1; *ch!='\0'; ch++) 
	X			switch (*ch) {
	X/*			case 'm':
	X				if (*(ch + 1) == '\0') {
	X					strcpy(macros, *++argv); 
	X					--argc;
	X					*ch = '\0';
	X				}
	X				else {
	X					strcpy(macros, ch + 1); 
	X					*(ch + 1) = '\0';
	X				}
	X				break;
	X*/
	X			default:
	X				fprintf(stderr, 
	X				    "Usage: stLgrind file\n");
	X				exit(-1);
	X				break;
	X			}
	X
	X	/* 
	X	 *	If there are any more arguments left, open that file and
	X	 *	set input to its fp.
	X	 */
	X
	X	if (argc == 0) {
	X		infp = stdin;
	X		strcpy(filename, "stdin");
	X	}
	X	else if (argc != 1) {
	X		fprintf(stderr, "Usage: stLgrind file\n");
	X		exit(-1);
	X	}
	X	else if ((infp = fopen(*argv, "r")) == NULL) {
	X		fprintf(stderr, "stLgrind: cannot open file: %s\n", *argv);
	X		exit(1);
	X	}
	X	else
	X		strcpy(filename, *argv);
	X}
	X
	X
	X/*
	X *	Returns the date string
	X */
	X
	Xchar *
	Xdate()
	X{
	X	long		now;
	X	char		*string;
	X	extern char	*ctime();
	X
	X	now = time(0);
	X	string = ctime(&now);
	X	string[24] = '\0';
	X	return(string);
	X}
SHAR_EOF
if test 14342 -ne "`wc -c < 'stLgrind.c'`"
then
	echo shar: error transmitting "'stLgrind.c'" '(should have been 14342 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

-- 
Herb Barad	[USC - Signal and Image Processing Institute]

USENET:		...!sdcrdcf!oberon!brand!barad			or
		...!mcvax!seismo!sdcsvax!sdcrdcf!oberon!brand!barad

ARPANET:	barad@brand.usc.edu