[net.micro.atari16] MAKE part 2 of 3

bammi@cwruecmp.UUCP (08/05/86)

#!/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:
#	main.c
#	make.c
#	makefile
#	makefile.mmc
#	mmcomp.sh
#	mmlink.sh
#	read.mee
#	reader.c
# This archive created: Tue Aug  5 02:46:37 1986
# By:	Jwahar R. Bammi ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'main.c'" '(6212 characters)'
if test -f 'main.c'
then
	echo shar: over-writing existing file "'main.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'main.c'
X#define ATARIST
X
X	/*******************************************************\
X	*							*
X	*	A full featured MAKE Clone			*
X	*							*
X	*	Origional Author: (Thank You)			*
X	*	    Neil Russell				*
X	*	    ACSnet:  caret@tictoc.oz			*
X	*	    UUCP:  ...!seismo!munnari!tictoc.oz!caret	*
X	*	    ARPA:  caret%tictoc.oz@seismo.arpa		*
X	*							*
X	*	Atari St Port & C code cleanup:			*
X	*	    Jwahar R. Bammi				*
X	*	    UUCP:  .....!decvax!cwruecmp!bammi		*
X	*	   CSNET:  bammi@case				*
X	*	    ARPA:  bammi%case@csnet-relay		*
X	*     CompuServe:  71515,155				*
X	*							*
X	\*******************************************************/
X		    
X
X/*
X *	make [-f makefile] [-ins] [target(s) ...]
X *
X *	(Better than EON mk but not quite as good as UNIX make)
X *
X *	-f makefile name
X *	-i ignore exit status
X *	-n Pretend to make
X *	-p Print all macros & targets
X *	-q Question up-to-dateness of target.  Return exit status 1 if not
X *	-r Don't not use inbuilt rules
X *	-s Make silently
X *	-t Touch files instead of making them
X *	-m Change memory requirements -- NOT in the Atari St version
X *
X *	>>>>> net.sources posting by:
X *
X *		Neil Russell
X *		ACSnet:  caret@tictoc.oz
X *		UUCP:  ...!seismo!munnari!tictoc.oz!caret
X *		ARPA:  caret%tictoc.oz@seismo.arpa
X *
X *	>>>>> 7/86 Jwahar R. Bammi  Added support for Atari ST
X *	   	report any Atari ST related complaints/suggestions to
X *	     	decvax!cwruecmp!bammi
X *	     	bammi@case.CSNET
X *	     	bammi%case@csnet-relay.ARPA
X *		71515,155
X */
X
X#include <stdio.h>
X#include "h.h"
X
X#ifndef ATARIST
X#include <sys/stat.h>
X#include <sys/err.h>
X
X#else
X#include "astat.h"
X
X#endif /* ATARIST */
X
X
X#ifndef ATARIST
X#define MEMSPACE	(16384)
X#endif /* ATARIST */
X
X
Xchar *			myname;
Xchar *			makefile = "";	/*  The make file  */
X
X#ifndef ATARIST
Xunsigned int		memspace = MEMSPACE;
X#endif /* ATARIST */
X
XFILE *			ifd;		/*  Input file desciptor  */
Xbool			domake = TRUE;	/*  Go through the motions option  */
Xbool			ignore = FALSE;	/*  Ignore exit status option  */
Xbool			silent = FALSE;	/*  Silent option  */
Xbool			print = FALSE;	/*  Print debuging information  */
Xbool			rules = TRUE;	/*  Use inbuilt rules  */
Xbool			dotouch = FALSE;/*  Touch files instead of making  */
Xbool			quest = FALSE;	/*  Question up-to-dateness of file  */
X
X
Xvoid
Xmain(argc, argv)
Xint			argc;
Xchar **			argv;
X{
X	register char *		p;	/*  For argument processing  */
X	int			estat = 0; /*  For question  */
X	register struct name *	np;
X	extern FILE *fopen();
X	extern int atoi();
X	extern char *index();
X
X#ifndef ATARIST
X	myname = (argc-- < 1) ? "make" : *argv++;
X#else
X	myname = "make";
X	argc--; argv++;
X#endif /* ATARIST - TOS does not pass the prog. name in argv[0] */
X
X	while ((argc > 0) && (**argv == '-'))
X	{
X		argc--;		/*  One less to process  */
X		p = *argv++;	/*  Now processing this one  */
X
X		while (*++p != '\0')
X		{
X			switch(*p)
X			{
X			case 'F': /* Goddamned MSDOS style shells pass caps */
X			case 'f':	/*  Alternate file name  */
X				if (*++p == '\0')
X				{
X					if (argc-- <= 0)
X						usage();
X					p = *argv++;
X				}
X				makefile = p;
X				goto end_of_args;
X#ifndef ATARIST
X			case 'm':	/*  Change space requirements  */
X				if (*++p == '\0')
X				{
X					if (argc-- <= 0)
X						usage();
X					p = *argv++;
X				}
X				memspace = atoi(p);
X				goto end_of_args;
X#endif /* ATARIST */
X			case 'N':
X			case 'n':	/*  Pretend mode  */
X				domake = FALSE;
X				break;
X
X			case 'I':
X			case 'i':	/*  Ignore fault mode  */
X				ignore = TRUE;
X				break;
X
X			case 'S':
X			case 's':	/*  Silent about commands  */
X				silent = TRUE;
X				break;
X			case 'P':
X			case 'p':
X				print = TRUE;
X				break;
X			case 'R':
X			case 'r':
X				rules = FALSE;
X				break;
X			case 'T':
X			case 't':
X				dotouch = TRUE;
X				break;
X			case 'Q':
X			case 'q':
X				quest = TRUE;
X				break;
X			default:	/*  Wrong option  */
X				usage();
X			}
X		}
X	end_of_args:;
X	}
X
X#ifndef ATARIST
X	if (initalloc(memspace) == 0xffff)  /*  Must get memory for alloc  */
X		fatal("Cannot initalloc memory");
X#endif /* ATARIST */
X
X	if (strcmp(makefile, "-") == 0)	/*  Can use stdin as makefile  */
X		ifd = stdin;	/* Will create havoc with Alcyons libs! */
X	else
X		if (*makefile == '\0')	/*  If no file, then use default */
X		{
X			if ((ifd = fopen(DEFN1, "r")) == (FILE *)0)
X#ifndef ATARIST
X				if (errno != ER_NOTF)
X					fatal("Can't open %s; error %02x", DEFN1, errno);
X#else
X				fatal("Can't open %s",DEFN1);
X			else
X				makefile = DEFN1;
X#endif /* ATARIST */
X
X#ifndef ATARIST
X			if ((ifd == (FILE *)0)
X				  && ((ifd = fopen(DEFN2, "r")) == (FILE *)0))
X				fatal("Can't open %s", DEFN2);
X#endif /* ATARIST */
X		}
X		else
X			if ((ifd = fopen(makefile, "r")) == (FILE *)0)
X				fatal("Can't open %s", makefile);
X
X	makerules();
X
X	setmacro("$", "$");
X
X	while (argc && ((p = index(*argv, '=')) != (char *)NULL))
X	{
X		char		c;
X
X		c = *p;
X		*p = '\0';
X		setmacro(*argv, p+1);
X		*p = c;
X
X		argv++;
X		argc--;
X	}
X
X
X	input(ifd);	/*  Input all the gunga  */
X	fclose(ifd);	/*  Finished with makefile  */
X	lineno = 0;	/*  Any calls to error now print no line number */
X
X
X	if (print)
X		prt();	/*  Print out structures  */
X
X	np = newname(".SILENT");
X	if (np->n_flag & N_TARG)
X		silent = TRUE;
X
X	np = newname(".IGNORE");
X	if (np->n_flag & N_TARG)
X		ignore = TRUE;
X
X	precious();
X
X	if (!domake)
X		silent = FALSE;
X
X	if (!firstname)
X		fatal("No targets defined");
X
X	circh();	/*  Check circles in target definitions  */
X
X
X	if (!argc)
X		estat = make(firstname, 0);
X	else while (argc--)
X	{
X		if (!print && !silent && strcmp(*argv, "love") == 0)
X			printf("Not war!\n");
X		estat |= make(newname(*argv++), 0);
X	}
X
X	if (quest)
X		exit(estat);
X	else
X		exit(0);
X}
X
X
Xusage()
X{
X#ifndef ATARIST
X	fprintf(stderr, "Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname);
X#else
X	fprintf(stderr, "Usage: make [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n");
X#endif /* ATARIST - argv[0] not passed by TOS - is Atari EVER going to fix this?? */
X	exit(1);
X}
X
X
Xvoid
Xfatal(msg, a1, a2, a3)
Xchar	*msg;
X#ifdef ATARIST
Xchar *a1;	/* Better be else you will get junk for a2 */
Xint a2, a3;
X#endif /* ATARIST - When will people learn that sizeof(int *) != sizeof(int) */
X{
X	fprintf(stderr, "%s: ", myname);
X	fprintf(stderr, msg, a1, a2, a3);
X	fputc('\n', stderr);
X	exit(1);
X}
SHAR_EOF
if test 6212 -ne "`wc -c 'main.c'`"
then
	echo shar: error transmitting "'main.c'" '(should have been 6212 characters)'
fi
echo shar: extracting "'make.c'" '(5900 characters)'
if test -f 'make.c'
then
	echo shar: over-writing existing file "'make.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'make.c'
X#define ATARIST
X
X	/*******************************************************\
X	*							*
X	*	A full featured MAKE Clone			*
X	*							*
X	*	Origional Author: (Thank You)			*
X	*	    Neil Russell				*
X	*	    ACSnet:  caret@tictoc.oz			*
X	*	    UUCP:  ...!seismo!munnari!tictoc.oz!caret	*
X	*	    ARPA:  caret%tictoc.oz@seismo.arpa		*
X	*							*
X	*	Atari St Port & C code cleanup:			*
X	*	    Jwahar R. Bammi				*
X	*	    UUCP:  .....!decvax!cwruecmp!bammi		*
X	*	   CSNET:  bammi@case				*
X	*	    ARPA:  bammi%case@csnet-relay		*
X	*     CompuServe:  71515,155				*
X	*							*
X	\*******************************************************/
X		    
X
X/*
X *	Do the actual making for make
X */
X
X#include <stdio.h>
X#include "h.h"
X
X#ifndef ATARIST
X#include <sys/stat.h>
X#include <sys/err.h>
X#else
X#include "astat.h"
X#endif /* ATARIST */
X
X
X#ifndef ATARIST
X/*
X *	Exec a shell that returns exit status correctly (/bin/esh).
X *	The standard EON shell returns the process number of the last
X *	async command, used by the debugger (ugg).
X *	[exec on eon is like a fork+exec on unix]
X */
Xint
Xdosh(string, shell)
Xchar *			string;
Xchar *			shell;
X{
X	int	number;
X
X	return ((number = execl(shell, shell,"-c", string, 0)) == -1) ?
X		-1:	/* couldn't start the shell */
X		wait(number);	/* return its exit status */
X}
X
X#else
X	 /* Atari St will use the system() function defined in ststuff.c */
X
X#define dosh(X,Y)	system(X)
X
X#endif /* ATARIST */
X
X/*
X *	Do commands to make a target
X */
Xvoid
Xdocmds(np)
Xstruct name *		np;
X{
X	bool			ssilent = silent;
X	bool			signore = ignore;
X	int			estat;
X	register char *		q;
X	register char *		p;
X	char *			shell;
X	register struct line *	lp;
X	register struct cmd *	cp;
X
X
X#ifndef ATARIST
X	if (*(shell = getmacro("SHELL")) == '\0')
X		shell = ":bin/esh";
X#endif /* ATARIST - does not have any standard shell */
X	
X	for (lp = np->n_line; lp; lp = lp->l_next)
X		for (cp = lp->l_cmd; cp; cp = cp->c_next)
X		{
X			strcpy(str1, cp->c_cmd);
X			expand(str1);
X			q = str1;
X			ssilent = silent;
X			signore = ignore;
X			while ((*q == '@') || (*q == '-'))
X			{
X				if (*q == '@')	   /*  Specific silent  */
X					ssilent = TRUE;
X				else		   /*  Specific ignore  */
X					signore = TRUE;
X				q++;		   /*  Not part of the command  */
X			}
X
X			if (!ssilent)
X				putchar('\t');
X
X			for (p=q; *p; p++)
X			{
X				if (*p == '\n' && p[1] != '\0')
X				{
X					*p = ' ';
X					if (!ssilent)
X						fputs("\\\n", stdout);
X				}
X				else if (!ssilent)
X					putchar(*p);
X			}
X			if (!ssilent)
X				putchar('\n');
X
X			if (domake)
X			{			/*  Get the shell to execute it  */
X				if ((estat = dosh(q, shell)) != 0)
X				{
X					if (estat == -1)
X#ifndef ATARIST
X						fatal("Couldn't execute %s", shell);
X#else
X						fatal("Couldn't execute %s", q);
X#endif /* ATARIST */
X					else
X					{
X						printf("%s: Error code %d", myname, estat);
X						if (signore)
X							fputs(" (Ignored)\n", stdout);
X						else
X						{
X							putchar('\n');
X							if (!(np->n_flag & N_PREC))
X								if (unlink(np->n_name) == 0)
X									printf("%s: '%s' removed.\n", myname, np->n_name);
X							exit(estat);
X						}
X					}
X				}
X			}
X		}
X}
X
X
X/*
X *	Get the modification time of a file.  If the first
X *	doesn't exist, it's modtime is set to 0.
X */
X#ifndef ATARIST
Xvoid
Xmodtime(np)
Xstruct name *		np;
X{
X	struct stat		info;
X	int			fd;
X
X
X	if ((fd = open(np->n_name, 0)) < 0)
X	{
X		if (errno != ER_NOTF)
X			fatal("Can't open %s; error %02x", np->n_name, errno);
X		np->n_time = 0L;
X	}
X	else if (getstat(fd, &info) < 0)
X		fatal("Can't getstat %s; error %02x", np->n_name, errno);
X	else
X		np->n_time = info.st_mod;
X
X	close(fd);
X}
X
X#else
X      /* Atari St version of modtime() using getstat() 
X       * see ststuff.c for Atari st version of getstat()
X       */
Xvoid
Xmodtime(np)
Xstruct name *		np;
X{
X	struct stat		info;
X	extern int		getstat();
X
X	if (getstat(np->n_name, &info) < 0)
X		np->n_time = 0L;
X	else
X	{
X		FlipWords(&info.st_mod);
X		np->n_time = info.st_mod;
X	}
X}
X#endif /* ATARIST */
X
X#ifndef ATARIST
X/*
X *	Update the mod time of a file to now.
X */
Xvoid
Xtouch(np)
Xstruct name *		np;
X{
X	char			c;
X	int			fd;
X
X
X	if (!domake || !silent)
X		printf("    touch %s\n", np->n_name);
X
X	if (domake)
X	{
X		if ((fd = open(np->n_name, 0)) < 0)
X			printf("%s: '%s' not touched - non-existant\n",
X					myname, np->n_name);
X		else
X		{
X			uread(fd, &c, 1, 0);
X			uwrite(fd, &c, 1);
X		}
X		close(fd);
X	}
X}
X
X# else
X/*
X *	Update the mod time of a file to now -- Atari St style
X */
X
Xvoid
Xtouch(np)
Xstruct name *np;
X{
X	register int	fd;
X
X
X	if (!domake || !silent)
X		printf("\ttouch %s\n", np->n_name);
X
X	if (domake)
X	{
X		if ((fd = Fopen(np->n_name, 0)) < 0)
X			printf("%s: '%s' not touched - non-existant\n",
X					myname, np->n_name);
X		else
X		{
X			long tim;
X
X			Fseek(0L, fd, 2); /* Seek to EOF */
X			tim = Gettime();
X			FlipWords(&tim);
X			Fdatime( &tim, fd,  1); /* This time the Hitch Hikers
X						 * guide is wrong
X					         */
X			Fclose(fd);
X		}
X	}
X}
X
X#endif /* ATARIST */
X
X/*
X *	Recursive routine to make a target.
X */
Xint
Xmake(np, level)
Xstruct name *		np;
Xint			level;
X{
X	register struct depend *	dp;
X	register struct line *		lp;
X	time_t				dtime = 1L;
X
X
X	if (np->n_flag & N_DONE)
X		return 0;
X
X	if (!np->n_time)
X		modtime(np);		/*  Gets modtime of this file  */
X
X	if (rules)
X	{
X		for (lp = np->n_line; lp; lp = lp->l_next)
X			if (lp->l_cmd)
X				break;
X		if (!lp)
X			dyndep(np);
X	}
X
X	if (!(np->n_flag & N_TARG) && np->n_time == 0L)
X		fatal("Don't know how to make %s", np->n_name);
X
X	for (lp = np->n_line; lp; lp = lp->l_next)
X		for (dp = lp->l_dep; dp; dp = dp->d_next)
X		{
X			make(dp->d_name, level+1);
X			dtime = max(dtime, dp->d_name->n_time);
X		}
X
X	np->n_flag |= N_DONE;
X
X	if (quest)
X	{
X		rtime(&np->n_time);
X		return np->n_time < dtime;
X	}
X	else if (np->n_time < dtime)
X	{
X		if (dotouch)
X			touch(np);
X		else
X		{
X			setmacro("@", np->n_name);
X			docmds(np);
X		}
X		rtime(&np->n_time);
X	}
X	else if (level == 0)
X		printf("%s: '%s' is up to date\n", myname, np->n_name);
X	return 0;
X}
SHAR_EOF
if test 5900 -ne "`wc -c 'make.c'`"
then
	echo shar: error transmitting "'make.c'" '(should have been 5900 characters)'
fi
echo shar: extracting "'makefile'" '(561 characters)'
if test -f 'makefile'
then
	echo shar: over-writing existing file "'makefile'"
fi
sed 's/^X//' << \SHAR_EOF > 'makefile'
X# Makefile for make
X
XBINDIR = d:\bin
X
XCPFLAGS = -i c:\include\ -DATARIST -DDECL
X
XOBJS1 = check.o input.o macro.o \
Xreader.o rules.o
X
XOBJS2 = main.o make.o ststuff.o
X
Xmake.prg : $(OBJS1) $(OBJS2) lnk
X	$(LINKER) [com[lnk]]
X	$(RELMOD) make
X	${ECHO} Break out the Champainge
X
Xtouch.prg: touch.o
X	$(LINKER) touch.68k=gemstart,touch,osbind,gemlib
X	$(RELMOD) touch
X	$(ECHO) touch made
X
X
X# Dependencies
X
X$(OBJS1) : h.h
X$(OBJS2) : h.h astat.h
X
Xclean:
X	$(RM) *.o *.68k
X
Xinstall: make.prg touch.prg
X	$(CP) make.prg $(BINDIR)\make.prg
X	$(CP) touch.prg $(BINDIR)\touch.prg
X
SHAR_EOF
if test 561 -ne "`wc -c 'makefile'`"
then
	echo shar: error transmitting "'makefile'" '(should have been 561 characters)'
fi
echo shar: extracting "'makefile.mmc'" '(475 characters)'
if test -f 'makefile.mmc'
then
	echo shar: over-writing existing file "'makefile.mmc'"
fi
sed 's/^X//' << \SHAR_EOF > 'makefile.mmc'
X# Makefile for make
X
XBINDIR = d:\bin
X
X
XOBJS1 = check.o input.o macro.o \
Xreader.o rules.o
X
XOBJS2 = main.o make.o ststuff.o
X
Xmake.prg : $(OBJS1) $(OBJS2)
X	$(LINKER) $(OBJS1) $(OBJS2) -o make.prg
X	${ECHO} Break out the Champainge
X
Xtouch.prg: touch.o
X	$(LINKER) touch.o -o touch.prg
X	$(ECHO) touch made
X
X# Dependencies
X
X$(OBJS1) : h.h
X$(OBJS2) : h.h astat.h
X
Xclean:
X	$(RM) *.o
X
Xinstall: make.prg touch.prg
X	$(CP) make.prg $(BINDIR)\make.prg
X	$(CP) touch.prg $(BINDIR)\touch.prg
SHAR_EOF
if test 475 -ne "`wc -c 'makefile.mmc'`"
then
	echo shar: error transmitting "'makefile.mmc'" '(should have been 475 characters)'
fi
echo shar: extracting "'mmcomp.sh'" '(84 characters)'
if test -f 'mmcomp.sh'
then
	echo shar: over-writing existing file "'mmcomp.sh'"
fi
sed 's/^X//' << \SHAR_EOF > 'mmcomp.sh'
Xmmlink check.o input.o macro.o main.o make.o reader.o rules.o ststuff.o -o make.prg
SHAR_EOF
if test 84 -ne "`wc -c 'mmcomp.sh'`"
then
	echo shar: error transmitting "'mmcomp.sh'" '(should have been 84 characters)'
fi
echo shar: extracting "'mmlink.sh'" '(84 characters)'
if test -f 'mmlink.sh'
then
	echo shar: over-writing existing file "'mmlink.sh'"
fi
sed 's/^X//' << \SHAR_EOF > 'mmlink.sh'
Xmmlink check.o input.o macro.o main.o make.o reader.o rules.o ststuff.o -o make.prg
SHAR_EOF
if test 84 -ne "`wc -c 'mmlink.sh'`"
then
	echo shar: error transmitting "'mmlink.sh'" '(should have been 84 characters)'
fi
echo shar: extracting "'read.mee'" '(757 characters)'
if test -f 'read.mee'
then
	echo shar: over-writing existing file "'read.mee'"
fi
sed 's/^X//' << \SHAR_EOF > 'read.mee'
Xmake.c:
X	* Fix dosh() for your system.
X	* Call to getstat() in modtime() is like a fstat() on unix,
X	  so it needs fixing.
Xmain.c:
X	* You can have fun in main().  That call to initalloc() is
X	  really special to EON.
Xrules.c:
X	* Fix makerules() to suit you compilers for the auto suffix
X	  stuff.
X
XIt supports most features of the UNIX make, the notable exceptions
Xbeing libraries, and some subtleties with quoting.  I will support
Xproblems with it to a degree.  Good luck.
X
XP.S.  I never actually got around to writing a manual entry for
X      it, so the best course of action is to refer to the UNIX
X      manual entry, or the source.
X
X
XNeil Russell
XACSnet:  caret@tictoc.oz
XUUCP:  ...!seismo!munnari!tictoc.oz!caret
XARPA:  caret%tictoc.oz@seismo.arpa
X
X
X
SHAR_EOF
if test 757 -ne "`wc -c 'read.mee'`"
then
	echo shar: error transmitting "'read.mee'" '(should have been 757 characters)'
fi
echo shar: extracting "'reader.c'" '(2569 characters)'
if test -f 'reader.c'
then
	echo shar: over-writing existing file "'reader.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'reader.c'
X#define ATARIST
X
X	/*******************************************************\
X	*							*
X	*	A full featured MAKE Clone			*
X	*							*
X	*	Origional Author: (Thank You)			*
X	*	    Neil Russell				*
X	*	    ACSnet:  caret@tictoc.oz			*
X	*	    UUCP:  ...!seismo!munnari!tictoc.oz!caret	*
X	*	    ARPA:  caret%tictoc.oz@seismo.arpa		*
X	*							*
X	*	Atari St Port & C code cleanup:			*
X	*	    Jwahar R. Bammi				*
X	*	    UUCP:  .....!decvax!cwruecmp!bammi		*
X	*	   CSNET:  bammi@case				*
X	*	    ARPA:  bammi%case@csnet-relay		*
X	*     CompuServe:  71515,155				*
X	*							*
X	\*******************************************************/
X		    
X
X/*
X *	Read in makefile
X */
X
X
X#include <stdio.h>
X#include <ctype.h>
X
X#include "h.h"
X
X
Xint			lineno = 0;
X
X
X/*
X *	Syntax error handler.  Print message, with line number, and exits.
X */
Xvoid
Xerror(msg, a1, a2, a3)
Xchar *			msg;
Xchar *a1;
Xint a2, a3;
X{
X	fprintf(stderr, "%s: ", myname);
X	fprintf(stderr, msg, a1, a2, a3);
X	if (lineno)
X		fprintf(stderr, " on line %d", lineno);
X	fputc('\n', stderr);
X	exit(1);
X}
X
X
X/*
X *	Read a line into the supplied string of length LZ.  Remove
X *	comments, ignore blank lines. Deal with	quoted (\) #, and
X *	quoted newlines.  If EOF return TRUE.
X */
Xbool
Xgetline(str, fd)
Xchar *		str;
XFILE *		fd;
X{
X	register char *		p;
X	char *			q;
X	int			pos = 0;
X	extern char *		fgets();
X
X	for (;;)
X	{
X		if(fgets((char *)((long)str + (long)pos), (int)(LZ-pos), fd) ==
X								     (char *)0)
X			return TRUE;		/*  EOF  */
X
X		lineno++;
X
X		if ((p = index((char *)((long)str+(long)pos), '\n')) ==
X								 (char *)0)
X			error("Line too long");
X
X		if (p[-1] == '\\')
X		{
X			p[-1] = '\n';
X			pos = (int)((long)p - (long)str);
X			continue;
X		}
X
X		p = str;
X		while (((q = index(p, '#')) != (char *)0) &&
X		    (p != q) && (q[-1] == '\\'))
X		{
X			char	*a;
X
X			a = q - 1;	/*  Del \ chr; move rest back  */
X			p = q;
X			while (*a++ = *q++)
X				;
X		}
X		if (q != (char *)0)
X		{
X			q[0] = '\n';
X			q[1] = '\0';
X		}
X
X		p = str;
X		while (isspace(*p))	/*  Checking for blank  */
X			p++;
X
X		if (*p != '\0')
X			return FALSE;
X		pos = 0;
X	}
X}
X
X
X/*
X *	Get a word from the current line, surounded by white space.
X *	return a pointer to it. String returned has no white spaces
X *	in it.
X */
Xchar *
Xgettok(ptr)
Xchar	**ptr;
X{
X	register char *		p;
X
X
X	while (isspace(**ptr))	/*  Skip spaces  */
X		(*ptr)++;
X
X	if (**ptr == '\0')	/*  Nothing after spaces  */
X		return NULL;
X
X	p = *ptr;		/*  word starts here  */
X
X	while ((**ptr != '\0') && (!isspace(**ptr)))
X		(*ptr)++;	/*  Find end of word  */
X
X	*(*ptr)++ = '\0';	/*  Terminate it  */
X
X	return(p);
X}
SHAR_EOF
if test 2569 -ne "`wc -c 'reader.c'`"
then
	echo shar: error transmitting "'reader.c'" '(should have been 2569 characters)'
fi
#	End of shell archive
exit 0
-- 
					Jwahar R. Bammi
 		        Usenet:  .....!decvax!cwruecmp!bammi
		        CSnet:  bammi@case         Arpa:  bammi%case@csnet-relay
			CompuServe:  71515,155