v08i054: Ease, a language for writing sendmail.cf files, Part02/04

sources-request at mirror.UUCP sources-request at mirror.UUCP
Thu Feb 12 06:29:50 AEST 1987


Submitted by: ksb at j.cc.purdue.edu
Mod.sources: Volume 8, Issue 54
Archive-name: ease/Part02


#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	src
if test ! -d src
then
mkdir src
echo "shar: part 01 is missing?"
fi
chdir src
cat << \SHAR_EOF > emitcf.c
/*	$Header: /usr/src/local/etc/ease/RCS/emitcf.c,v 1.3 85/11/22 20:14:11 jss Exp $	*/

/*
 *	emitcf.c  -- This file contains routines associated with the writing
 *		     and formatting of a translated sendmail configuration file.
 *
 *	author	  -- James S. Schoner, Purdue University Computing Center,
 *			  	       West Lafayette, Indiana  47907
 *
 *  	date	  -- July 9, 1985
 *
 *	Copyright (c) 1985 by Purdue Research Foundation
 *
 *	All rights reserved.
 *
 */

#include <stdio.h>
#include "symtab.h"

#define REGLINE 60	/* length of output lines which may be continued */
#define MAXLINE 256	/* liberal maximum line length			 */

extern short Rformat;			/* read-format flag for a class  */
extern char *MacScan ();
extern char  MakeMac ();
extern void  PrintError (),
	     FatalError (),
	     PrintWarning (),
	     ErrorReport ();

void  PrintDef ();

static char ClassCH;			/* printable class macro char    */

/*
 *	EmitDef () -- Emit a definition line (Ease block definition) in cf 
 *		      format.
 *
 */
void
EmitDef (blockdef, targ, defstr1, defstr2)
register enum bdefs blockdef;	/* type of definition   	 */
register struct he *targ;	/* target to be defined 	 */
char *defstr1, *defstr2;	/* one or two definition strings */
{
	/*
	 *  This routine is about as pretty as a translated ease file...
	 *  Each type of line (Ease block) is handled case by case below.
	 *
	 */
	switch (blockdef) {
		case def_macro:		printf ("D%c", MakeMac (targ, ID_MACRO));
					PrintDef (def_macro, MacScan (defstr1));
					if (ISMACRO(targ->idd))
						PrintWarning ("Redefining macro %s.\n", targ->psb);
					targ->idd |= ID_MACRO;  /* signal definition */
					break;

		case def_class:		if (Rformat)	/* read format */
						printf ("F");
					else
						printf ("C");
					printf ("%c", ClassCH = MakeMac (targ, ID_CLASS));
					if (Rformat) {	/* read format */
						printf ("%s\n", defstr1);
						Rformat = FALSE;
					} else
						PrintDef (def_class, defstr1);
					if (ISCLASS(targ->idd))
						PrintWarning ("Redefining class %s.\n", targ->psb);
					targ->idd |= ID_CLASS;  /* signal definition */
					break;

		case def_option:	printf ("O%c", *defstr1);
					PrintDef (def_option, defstr2);
					break;

		case def_prec:		printf ("P%s=%d\n", targ->psb, targ->idval.prec);
					break;

		case def_trusted:	printf ("T");
					PrintDef (def_trusted, defstr1);
					break;

		case def_header:	printf ("H");
					if (defstr1 != NULL)
						printf ("?%s?", defstr1);
					PrintDef (def_header, defstr2);
					break;

		case def_mailer:	if (ISMAILER(targ->idtype)) {
						if (ISMAILER(targ->idd))
							PrintWarning ("Redefining mailer %s.\n", targ->psb);
					} else if (ISTYPED(targ->idtype)) {
						PrintError ("Redeclaration of identifier as mailer:", targ->psb);
						return;
					}
					targ->idd |= ID_MAILER;  /* signal definition */
					printf ("M%s, ", targ->psb);
					PrintDef (def_mailer, defstr1);
					break;

		case def_ruleset:	printf ("R");
					PrintDef (def_ruleset, defstr1);
					break;

		default:		FatalError ("Bad case in EmitDef ()", (char *) NULL);
	}
}


/*
 *  	PrintContinued () -- Print a line definition (buf) by splitting it over
 *			     more than one line.  The two definition types 
 *			     accepted for this method of continuation are class
 *			     and trusted user lists, indicated in the argument 
 *			     btype 
 *
 */
void
PrintContinued (btype, buf)
enum bdefs     btype;	/* block (line) type for definition */
register char *buf;	/* buffer containing the definition */
{
	register char *tmp;	/* breakpoint search pointer   */
	register char  tc;	/* temporary swap byte         */
	int  buflen;		/* length of definition buffer */	

	buflen = strlen (buf);
	tmp = buf + REGLINE;
	while ((*--tmp != ' ') && (tmp != buf))	 /* look for suitable break */
		/* null */ ;
	if (tmp == buf) {
		for (tmp = buf + REGLINE; (*tmp != ' ') && (tmp - buf != buflen); tmp++)
			/* null */ ;
		if ((tmp - buf) >= MAXLINE)
			PrintWarning ("Member name may be too long.\n", (char *) NULL);
	}
	tc = *tmp;		/* swap break char with null char */
	*tmp = '\0';
	printf ("%s\n", buf);
	if ((*tmp = tc) == '\0')
		return;
	else
		tmp++;
	if (btype == def_class)		/* start next line   */
		printf ("C%c", ClassCH);
	else
		printf ("T");
	if (strlen (tmp) < REGLINE)	/* continue the line */
		printf ("%s\n", tmp);
	else
		PrintContinued (btype, tmp);
}


/*
 *	PrintDef () -- Handles special cases (like line continuation) when 
 *		       printing definitions.
 *
 */
void
PrintDef (btype, dstr)
register enum bdefs btype;	/* block type (output line type) */
register char *dstr;		/* definition string		 */
{
	register char *tmp;

	for (tmp = dstr; *tmp != '\0'; tmp++) 	/* search for line continuations */
		if ((*tmp == '\\') && (*++tmp == '\n'))
			if (btype != def_header) {
				ErrorReport ("Non-header string contains line continuation\n");
				return;
			} else
				break;

	/*
	 *  Perform case by case handling of definition printing.
	 *
	 */
	switch (btype) {
		case def_header :  if (*tmp-- == '\n') {
					*tmp = '\0';
					if (tmp - dstr >= MAXLINE)
						PrintWarning ("Header may be too long.\n", 
							      (char *) NULL);
					printf ("%s\n\t", dstr);
					tmp += 2;
				        PrintDef (def_header, tmp);
				   } else {
					if (strlen (dstr) >= MAXLINE)
						PrintWarning ("Header may be too long.\n", 
							      (char *) NULL);
					printf ("%s\n", dstr);
				   }
				   break;

		case def_mailer :  if (strlen (dstr) >= MAXLINE)
					PrintWarning ("Mailer definition may be too long.\n", 
						      (char *) NULL);
				   printf ("%s\n", dstr);
				   break;

		case def_ruleset:  if (strlen (dstr) >= MAXLINE)
					PrintWarning ("Rewriting rule may be too long.\n", 
						      (char *) NULL);
				   printf ("%s\n", dstr);
				   break;

		case def_option :  if (strlen (dstr) >= MAXLINE)
					PrintWarning ("Option assignment may be too long.\n", 
						      (char *) NULL);
				   printf ("%s\n", dstr);
				   break;

		case def_macro  :  if (strlen (dstr) >= MAXLINE)
					PrintWarning ("Macro assignment may be too long.\n", 
						      (char *) NULL);
				   printf ("%s\n", dstr);
				   break;

		case def_prec   :  if (strlen (dstr) >= MAXLINE)
					PrintWarning ("Precedence relation may be too long.\n", 
						      (char *) NULL);
				   printf ("%s\n", dstr);
				   break;

		case def_trusted:
		case def_class  :  if (strlen (dstr) < REGLINE)
					printf ("%s\n", dstr);
				   else		/* use line continuation feature */
				   	PrintContinued (btype, dstr);
				   break;

		default         :  FatalError ("Invalid case in PrintDef ()", (char *) NULL);
	}
}


/*
 *	StartRuleset () -- Prints a ruleset heading for the ruleset identifier
 *		           contained in the argument rsid.
 *
 */
void
StartRuleset (rsid)
register struct he *rsid;	/* ruleset identifier */
{
	if (!ISRULESET(rsid->idtype))
		if (ISTYPED(rsid->idtype))
			PrintError ("Identifier not of ruleset type:", rsid->psb);
		else
			PrintError ("Ruleset identifier not bound to a number:", rsid->psb);
	else {
		if (ISRULESET(rsid->idd))
			PrintWarning ("Redefining ruleset %s.\n", rsid->psb);
		rsid->idd |= ID_RULESET;
		printf ("S%s\n", rsid->idval.rsn);
	}
}
SHAR_EOF
if test 7227 -ne "`wc -c emitcf.c`"
then
echo shar: error transmitting emitcf.c '(should have been 7227 characters)'
fi
cat << \SHAR_EOF > errors.c
/*	$Header: /usr/src/local/etc/ease/RCS/errors.c,v 1.2 85/10/29 23:40:20 jss Exp $	*/

/*
 *  	errors.c   -- Contains error initialization and reporting routines.
 *
 *  	author     -- James S. Schoner, Purdue University Computing Center,
 *				        West Lafayette, Indiana  47907
 *
 *  	date       -- July 9, 1985
 *
 *	Copyright (c) 1985 by Purdue Research Foundation
 *
 *	All rights reserved.
 *
 */

#include <stdio.h>

extern int  ErrorCount;	 /* error count	               */
extern char FNbuf[];	 /* input file name   	       */
extern int  Lcount;	 /* line count	     	       */
FILE *DIAGf = {stderr};  /* file for diagnostic output */


/*
 *	ErrorReport () -- Prints source file name (FNbuf), line number (Lcount),
 *			  and error message (sbErr) for each invokation.
 *
 */
void
ErrorReport (sbErr)
char *sbErr;
{
	fprintf (DIAGf, "%s, line %d: %s", FNbuf, Lcount, sbErr);
	ErrorCount++;
}


/*
 *	FatalError () -- Translator fatal error routine which prints 
 *			 error message (sbErr) and an argument (sbArg).
 *
 */
void
FatalError (sbErr, sbArg)
char *sbErr,
     *sbArg;
{
	fprintf (DIAGf, "%s, line %d: Fatal Error In Translator: %s %s\n", 
		 FNbuf, Lcount, sbErr, sbArg);
	exit (1);
}


/*
 *	yyerror () -- Prints source file name (FNbuf), line number (Lcount),
 *		      and error message (sbErr) for each invokation.
 *
 */
void
yyerror (sbErr)
char *sbErr;
{
	fprintf (DIAGf, "%s, line %d: %s\n", FNbuf, Lcount, sbErr);
	ErrorCount++;
}


/*
 *	PrintError () -- Prints source file name (FNbuf), line number
 *			 (cline), error message (sbErr), and argument
 *			 (sbArg) for each invokation.
 *
 */
void
PrintError (sbErr, sbArg)
char *sbErr;
char *sbArg;
{
	fprintf (DIAGf, "%s, line %d: %s %s.\n", FNbuf, Lcount, sbErr, sbArg);
	ErrorCount++;
}


/*
 *	PrintWarning () -- Prints a warning message with source file
 *			   name (FNbuf), line number (Lcount), warning
 *			   (sbWarn), and a possible identifier (sbID).
 *
 */
void
PrintWarning (sbWarn, sbID)
char *sbWarn;
char *sbID;
{
	fprintf (DIAGf, "%s, line %d: Warning: ", FNbuf, Lcount);
	if (sbID != NULL)
		fprintf (DIAGf, sbWarn, sbID);
	else
		fprintf (DIAGf, sbWarn);
}


/*
 *	InitError () -- Initialize line count (Lcount) to one and error count
 *		        (ErrorCount) to zero.
 *
 */
void
InitError ()
{
	Lcount     = 1;
	ErrorCount = 0;
}
SHAR_EOF
if test 2340 -ne "`wc -c errors.c`"
then
echo shar: error transmitting errors.c '(should have been 2340 characters)'
fi
cat << \SHAR_EOF > idman.c
/*	$Header: /usr/src/local/etc/ease/RCS/idman.c,v 1.2 85/10/29 23:41:38 jss Exp $	*/

/*
 *  	idman.c	-- Contains routines for manipulating identifiers and their
 *		   symbolic associations.
 *
 *  	author	-- James S. Schoner, Purdue University Computing Center,
 *				     West Lafayette, Indiana  47907
 *
 *  	date	-- July 9, 1985
 *
 *	Copyright (c) 1985 by Purdue Research Foundation
 *
 *	All rights reserved.
 *
 */

#include <stdio.h>
#include "symtab.h"

extern struct he *LookupSymbol ();
extern void	  FatalError (),
		  ErrorReport (),
		  PrintWarning (),
		  PrintError ();

short Uchar = 'A';			/* for unique macro names */


/*
 *	UniqMac () -- Assigns and returns a unique one-character macro
 *		      name (upper-case) for an Ease macro name.
 *
 */
char
UniqMac (phe)
struct he *phe;		/* symbol table entry for Ease macro */
{
	if ((phe->idval.idc = Uchar++) > 'Z')
		FatalError ("Too many macro names (26 max)", (char *) NULL);
	return (phe->idval.idc);
}


/*
 *	BindID () -- Binds either a ruleset or precedence identifier (phe) to
 * 		     an integer (vid).  The id type distinction is passed in
 *		     the parameter idt.
 *
 */
void
BindID (phe, vid, idt)
register struct he *phe;	/* symbol table entry for an identifier    */
int vid;			/* value of the identifier		   */
unsigned idt;			/* identifier type (ruleset or precedence) */
{
	if (ISTYPED(phe->idtype)) {	/* should be undefined */
		PrintWarning ("Redeclaration of %s.\n", phe->psb);
		phe->idtype = ID_UNTYPED;
	}
	phe->idtype |= idt;		/* make defined	       */
	if (ISRULESET(phe->idtype)) {
		if (vid > VALRSNMAX) {
			ErrorReport ("Ruleset number too large.\n");
			return;
		} else if (vid < 0) {
			ErrorReport ("Ruleset number must be non-negative.\n");
			return;
		}
		sprintf (phe->idval.rsn, "%d", vid);
	} else 
		phe->idval.prec = vid;
}


/*
 *	CheckRS () -- Checks validity of a ruleset identifier (phe) and 
 *		      returns the ruleset string to which the identifier
 *		      is bound.  If the ruleset identifier is invalid, the
 *		      null string is returned.
 *
 */
char *
CheckRS (phe)
struct he *phe;		/* symbol table entry for ruleset identifier */
{
	if (!ISRULESET(phe->idtype)) {
		if (!ISTYPED(phe->idtype))
			PrintError ("Ruleset identifier not bound to a number:", phe->psb);
		else
			PrintError ("Identifier not of ruleset type:", phe->psb);
		return (NULL);
	} else
		return (phe->idval.rsn);
}


/*
 *	MakeMac () -- Declare a macro name (pmac) as a class and/or macro type 
 *		      (targtype) and return the unique cf character assigned 
 *		      to it.
 *
 */
char
MakeMac (pmac, targtype)
register struct he *pmac;	/* symbol table entry for macro identifier */
unsigned targtype;		/* target declaration type for the macro   */
{
	/*
	 *	An Ease macro may be declared as both a singular macro and
	 *	a class macro.
	 *
	 */
	if (ISMACRO(pmac->idtype) || ISCLASS(pmac->idtype)) {
		pmac->idtype |= targtype;
		return (pmac->idval.idc);
	}
	if (ISTYPED(pmac->idtype)) {	/* not a macro or class id */
		PrintError ("Redeclaring or using as macro or class:", pmac->psb);
		return ('\0');
	}
	pmac->idtype |= targtype;	/* previously untyped; declare here */
	return (UniqMac (pmac));
}
	

/*
 *	GetField () -- Returns a field type string given a field 
 *		       identifier (fid).
 *
 */
char *
GetField (fid)
register struct he *fid;	/* field identifier */
{
	if (!ISFIELD(fid->idtype)) {
		PrintError ("Field type not defined for", fid->psb);
		return (NULL);
	} else 
		return (fid->idval.fstring);
}


/*
 *	CheckMailer () -- Declares a mailer identifier (mid) as type mailer,
 *			  checking that the identifier was not previously 
 *			  declared a different type. 
 *
 */
char *
CheckMailer (mid)
register struct he *mid;
{
	if (ISTYPED (mid->idtype) && !ISMAILER (mid->idtype)) {
		PrintError ("Redeclaration as mailer:", mid->psb);
		return (NULL);
	}
	mid->idtype |= ID_MAILER;
	return (mid->psb);
}


/*
 *	AssignType () -- Assigns to each field identifier in fidlist the
 *			 type (in string form) fidtype.  This is accomplished
 *			 by making each field identifier symbol table entry
 *			 "point" to the type found in fidtype.
 *
 */
void
AssignType (fidlist, fidtype)
register char *fidlist;		/* field identifier list, blank separated */
char *fidtype;			/* field identifier type string		  */
{
	register struct he *fid;	/* pointer to a field identifier  */
	char *fres;			/* field type result string	  */
	register char *srch;		/* fidlist search pointer	  */
	char  sep;			/* fidlist separator character    */

	fres = (char *) malloc (strlen (fidtype) + 1);
	if (fres == NULL)
		FatalError ("System out of string space in AssignType ()", (char *) NULL);
	strcpy (fres, fidtype);		/* make clean copy of string type */

	/*
	 *	Search for all field identifiers and make the type assignment. 
 	 *
	 */
	srch = fidlist;
	while (*srch != '\0') {
		while ((*++srch != ' ') && (*srch != '\0'))
			/* null */ ;
		if (*fidlist != '\0') {		        /* found a field id       */
			sep = *srch;
			*srch = '\0';
			fid = LookupSymbol (fidlist);	/* get symbol table entry */
			if (ISFIELD(fid->idtype)) {
				if (strcmp (fid->idval.fstring, fres))
					PrintWarning ("Redefinition of field type for %s.\n", fid->psb);
			} else if (ISTYPED(fid->idtype)) {
				PrintError ("Redeclaration of identifier as a field:", fid->psb);
				return;
			}
			fid->idtype |= ID_FIELD;	/* type the identifier    */
			fid->idval.fstring = fres;	/* type the field	  */
			if ((*srch = sep) != '\0')
				fidlist = ++srch;
		}
	}
}
SHAR_EOF
if test 5550 -ne "`wc -c idman.c`"
then
echo shar: error transmitting idman.c '(should have been 5550 characters)'
fi
cat << \SHAR_EOF > main.c
/*	$Header: /usr/src/local/etc/ease/RCS/main.c,v 1.2 85/10/29 23:43:38 jss Exp $	*/

/*
 *  	main.c     -- Main procedure for Ease Translator.
 *
 *  	author     -- James S. Schoner, Purdue University Computing Center
 *				        West Lafayette, Indiana  47907
 *
 *  	date       -- July 9, 1985
 *
 *	Copyright (c) 1985 by Purdue Research Foundation
 *
 *	All rights reserved.
 *
 */

#include <stdio.h>

extern FILE *DIAGf;			/* diagnostic file */
extern void InitError (), 
	    InitSymbolTable (),
	    DefScan (),
	    FatalError (),
            PreLoad ();

int ErrorCount;				/* translation error count */
void GetArgs ();			/* gets arguments to "et"  */

/*
 *	main () -- Main procedure for the Ease Translator et.  If no files are 
 *	       	   given as arguments to et, stdin is translated and written to 
 *	           stdout.  If one file is given, it is translated and written 
 *	           to stdout.  If two files are given, the first is translated
 *	           and written to the second.  If the first filename is "-",
 *	           standard input is assumed.  A translation is performed on 
 *	           valid Ease input only, producing a regular sendmail 
 *		   configuration file. 
 *
 */
void
main (argc, argv)
int argc;		/* argument count for "et"  */
char *argv[];		/* argument vector for "et" */
{
	InitError ();			/* initialize error conditions */
	InitSymbolTable ();		/* initialize the symbol table */
	PreLoad ();			/* preload special identifiers */
	GetArgs (argc, argv);		/* set up argument files       */
	(void) yyparse ();		/* perform translation	       */
	if (fflush (stdout) == EOF)
		FatalError ("Cannot flush output stream/file", (char *) NULL);
	DefScan ();		        /* warn about undefined idents */
	if (ErrorCount)
		fprintf (DIAGf, "\n\n*** %d error(s) detected.\n", ErrorCount);
	exit (ErrorCount);
}


/*
 *	GetArgs () -- Processes arguments to the Ease translator "et".  The
 *		      arguments are files (margv) which may replace either/both
 *		      of the files standard input and standard output.  The 
 *		      following cases are possible:
 *			
 *		      -- et f.e f.cf
 *				Translate Ease file f.e and write result
 *				to f.cf.
 *
 *		      -- et f.e
 *				Translate Ease file f.e and write result to
 *				standard output.
 *
 *		      -- et - f.cf
 *				Translate standard input and write result to
 *				f.cf.
 *
 *		      -- et
 *				Translate standard input and write result to
 *				standard output.
 *
 *		      Finally, a message indicating the volatility of the 
 *		      Ease output is written.
 *
 */
void
GetArgs (margc, margv)
register int   margc;		/* argument count  */
register char *margv[];		/* argument vector */
{
	switch (margc) {
		case 1 : break;
		case 2 :
		case 3 : if (strcmp (margv[1], "-") && (freopen (margv[1], "r", stdin) == NULL))
				FatalError ("Cannot open input stream/file:", margv[1]);
			 if ((margc == 3) && (freopen (margv[2], "w", stdout) == NULL))
				FatalError ("Cannot open output file:", margv[2]);
			 break;
		default: FatalError ("Usage: et [infile [outfile]]", (char *) NULL);
			 break;
	}
	printf ("###################################################\n");
	printf ("##                                               ##\n");
	printf ("##  WARNING: THIS FILE IS TO BE MODIFIED BY      ##\n");
	printf ("##           THE EASE TRANSLATOR (ET) ONLY.      ##\n");
	printf ("##                                               ##\n");
	printf ("##           ALL OTHER MODIFICATIONS WILL        ##\n");
	printf ("##           DISAPPEAR THE NEXT TIME ET IS RUN.  ##\n");
	printf ("##                                               ##\n");
	printf ("##           MAKE MODIFICATIONS TO THE EASE      ##\n");
	printf ("##           SOURCE ONLY.                        ##\n");
	printf ("##                                               ##\n");
	printf ("###################################################\n");
}
SHAR_EOF
if test 3915 -ne "`wc -c main.c`"
then
echo shar: error transmitting main.c '(should have been 3915 characters)'
fi
cat << \SHAR_EOF > strops.c
/*	$Header: /usr/src/local/etc/ease/RCS/strops.c,v 1.2 85/10/29 23:45:39 jss Exp $	*/

/*
 *	strops.c   -- Contains string operation routines used for constructing
 *		      definitions in cf format.
 *
 *	author	   -- James S. Schoner, Purdue University Computing Center,
 *				        West Lafayette, Indiana  47907
 *
 *	date	   -- July 9, 1985
 *
 *	Copyright (c) 1985 by Purdue Research Foundation
 *
 *	All rights reserved.
 *
 */

#include <stdio.h>
#include <strings.h>
#include "symtab.h"

#define MAXTOKPOS   99		/* maximum number of token positions */
#define MAXNAME	    1024	/* maximum length of an identifier   */

extern struct he *LookupSymbol ();
extern char       MakeMac ();
extern void	  FatalError (),
		  PrintError (),
		  ErrorReport ();

short  Rformat = FALSE;			/* class read format flag	  */
static char   *Ptok   = "$  ";		/* positional token structure     */
static char   *Cfield = "$= ";		/* class reference structure	  */
static char   *Ofield = "$-";		/* one token match structure	  */
static char   *Zfield = "$*";		/* zero or more tokens structure  */
static char   *Pfield = "$+";		/* one or more tokens structure	  */
static char   *Mtest  = "$? ";		/* conditional macro test string  */


/*
 *	ConvOpt () -- Convert an Ease option identifier (optid) by returning a
 *		      string representation of the cf format.  
 *
 */
char *
ConvOpt (optid) 
register enum opts optid;
{
	switch (optid) {
		case opt_A  :	return ("A");
		case opt_a  :	return ("a");
		case opt_B  :	return ("B");
		case d_opt_b:	return ("b");
		case opt_c  :	return ("c");
		case opt_D  :	return ("D");
		case opt_d  :	return ("d");
		case opt_e  :
		case e_opt_e:	return ("e");
		case opt_F  :	return ("F");
		case opt_f  :	return ("f");
		case opt_g  :	return ("g");
		case opt_H  :	return ("H");
		case opt_i  :
		case d_opt_i:	return ("i");
		case opt_L  :	return ("L");
		case opt_m  :
		case e_opt_m:	return ("m");
		case opt_N  :	return ("N");
		case opt_o  :	return ("o");
		case e_opt_p:	return ("p");
		case opt_Q  :	return ("Q");
		case d_opt_q:	return ("q");
		case opt_r  :	return ("r");
		case opt_S  :	return ("S");
		case opt_s  :	return ("s");
		case opt_T  :	return ("T");
		case opt_t  :	return ("t");
		case opt_u  :	return ("u");
		case opt_v  :	return ("v");
		case opt_W  :	return ("W");
		case e_opt_w:	return ("w");
		case opt_x  :	return ("x");
		case opt_X  :	return ("X");
		case e_opt_z:	return ("z");
		default     :	FatalError ("Bad case in ConvOpt ()", (char *) NULL);
	}
	/*NOTREACHED*/
}


/*
 *	ConvFlg () -- Convert an Ease mailer flag identifier (flgid) by 
 *		      string representation of the cf format.  
 *
 */
char *
ConvFlg (flgid)
register enum flgs flgid;	/* flag identifier */
{
	switch (flgid) {
		case flg_f:	return ("f");
		case flg_r:	return ("r");
		case flg_S:	return ("S");
		case flg_n:	return ("n");
		case flg_l:	return ("l");
		case flg_s:	return ("s");
		case flg_m:	return ("m");
		case flg_F:	return ("F");
		case flg_D:	return ("D");
		case flg_M:	return ("M");
		case flg_x:	return ("x");
		case flg_P:	return ("P");
		case flg_u:	return ("u");
		case flg_h:	return ("h");
		case flg_A:	return ("A");
		case flg_U:	return ("U");
		case flg_e:	return ("e");
		case flg_X:	return ("X");
		case flg_L:	return ("L");
		case flg_p:	return ("p");
		case flg_I:	return ("I");
		case flg_C:	return ("C");
		default   :	FatalError ("Bad case in ConvFlg ()", (char *) NULL);
	}
	/*NOTREACHED*/
}


/*
 *	ConvMat () -- Convert an Ease mailer attribute (mat) by returning a
 *		      string representation of the cf format.  
 *
 */
char *
ConvMat (mat)
register enum mats mat;		/* mailer attribute flag */
{
	switch (mat) {
		case mat_path		: return ("P");
		case mat_flags		: return ("F");
		case mat_sender		: return ("S");
		case mat_recipient	: return ("R");
		case mat_argv		: return ("A");
		case mat_eol		: return ("E");
		case mat_maxsize	: return ("M");
		default			: FatalError ("Bad case in ConvMat ()", (char *) NULL);
	}
	/*NOTREACHED*/
}


/*
 *	MacScan () -- Scan a string (pstring) for macros, replacing the Ease
 *		      form with the one-character form required by cf format.
 *
 */
char *
MacScan (pstring)
char *pstring;		/* macro expandable string */
{
	register char *searchptr;	/* string search pointer 	*/
	register char *bptr, *eptr;	/* macro begin and end pointers */
	char macname [MAXNAME];		/* macro name buffer		*/

	if ((searchptr = pstring) == NULL)
		return ((char *) NULL);
	while (*searchptr != '\0') 	/* find and rewrite all macros  */
		if (*searchptr == '\\') {
			searchptr = searchptr + 2;
			continue;
		} else if (*searchptr++ == '$' && *searchptr == '{') {
			if (sscanf (searchptr + 1, "%[^}]", macname) != 1) {
				PrintError ("Invalid macro format:", searchptr + 1);
				return ((char *) NULL);
			} 
			*searchptr++ = MakeMac (LookupSymbol (macname), ID_MACRO);
			bptr = eptr = searchptr;
			while (*eptr++ != '}')	/* delete old macro chars */
				/* empty */ ;
			do
				*bptr++ = *eptr;
			while (*eptr++ != '\0');
		}
	return (pstring);
}


/*
 *	MakeRStr () -- Construct and return a pointer to a class read string 
 *		       using the filename fname and read format rformat.  
 *
 */
char *
MakeRStr (fname, rformat)
char *fname,			/* file name for class read */
     *rformat;			/* format for class read    */
{
	register char *res;	/* resultant read string    */

	Rformat = TRUE;		/* set read format flag     */
	if (rformat == NULL)
		return (fname);
	res = (char *) realloc (fname, strlen (fname) + strlen (rformat) + 2);
	if (res == NULL)
		FatalError ("System out of string space in MakeRStr ()", (char *) NULL);
	res = strcat (res, " ");	/* construct read string */
	res = strcat (res, rformat);
	free (rformat);
	return (res);
}


/*
 *	ListAppend () -- Append string list2 to string list1 using the 
 *			 separator sep.  A pointer to the newly constructed
 *			 string is returned.
 *
 */
char *
ListAppend (list1, list2, sep)
char *list1,			/* first string 	*/
     *list2,			/* second string  	*/
     *sep;			/* string separator	*/
{
	register char *res;	/* resultant string	*/

	res = (char *) malloc (strlen (list1) + strlen (list2) + strlen (sep) + 1);
	if (res == NULL)
		FatalError ("System out of string space in ListAppend ()", (char *) NULL);
	res = strcpy (res, list1);
	if (list1 != NULL)	/* use separator if first string not null */
		res = strcat (res, sep);
	res = strcat (res, list2);
	return (res);
}


/*
 *	MakeCond () -- Construct a macro conditional string in cf format.  The
 *		       conditional is based on the macro testmac, with an "if
 *		       set" result ifstring, which may contain an optional 
 *		       "if not set" result string appended to it.
 *
 */
char *
MakeCond (testmac, ifstring)
struct he *testmac;		/* macro for conditional testing 	     */
char 	  *ifstring; 		/* "if macro set" result string(s)  	     */
{
	register char *res;	/* resultant conditional string		     */

	Mtest[2] = MakeMac (testmac, ID_MACRO);	   /* get one-char macro rep */
	res = (char *) malloc (strlen (ifstring) + 6);
	if (res == NULL)
		FatalError ("System out of string space in MakeCond ()", (char *) NULL);
	res = strcpy (res, Mtest);
	res = strcat (res, ifstring);		/* build result part	  */
	res = strcat (res, "$.");		/* end of conditional     */
	free (ifstring);
	return (res);
}


/*
 *	MakePosTok () -- Construct and return a positional token string 
 *			 representation from the parameter num.
 *
 */
char *
MakePosTok (num)
register int num;	        /* numerical value of positional token */
{
	if (num > MAXTOKPOS) {
		ErrorReport ("Positional token too large.\n");
		return ((char *) NULL);
	} else {
		if (num > 9) {	/* two-digit positional token */
			Ptok[1] = '0' + (num / 10);
			Ptok[2] = '0' + (num % 10);
			Ptok[3] = '\0';
		} else {
			Ptok[1] = '0' + num;
			Ptok[2] = '\0';
		}
	return (Ptok);
	}
}


/*
 *	Bracket () -- Construct and return a cf string form of the 
 *		      canonicalization of the string identifier passed in
 *		      the string parameter psb if dflag is true, else
 *		      simply bracket the identifier without dollar signs
 *		      for numeric hostname specifications.
 *
 */
char *
Bracket (psb, dflag)
char *psb;			/* identifier to be canonicalized */
short dflag;			/* dollar flag 			  */
{
	register char *res;	/* resultant cf form 		  */
	register short extra;	/* extra space needed for malloc  */
	
	extra = dflag ? 5 : 3;
	res = (char *) malloc (strlen (psb) + extra);
	if (res == NULL)
		FatalError ("System out of string space in Bracket ()", (char *) NULL);
	if (dflag)
		res = strcpy (res, "$[");
	else
		res = strcpy (res, "[");
	res = strcat (res, psb);
	if (dflag)
		res = strcat (res, "$");
	res = strcat (res, "]");
	return (res);
}


/*
 *	MakeRSCall () -- Construct and return a cf string form of a call
 *			 to a ruleset (cid), which would pass to it the
 *			 remainder of a rewriting address (rwaddr).
 *
 */
char *
MakeRSCall (cid, rwaddr)
register struct he *cid;	/* called ruleset identifier	     */
register char *rwaddr;		/* remainder of rewriting address    */
{
	register char *res;	/* resultant cf string for the call  */
	
	if (!ISRULESET(cid->idtype)) {	/* check validity of ruleset */
		PrintError ("Undefined ruleset identifier:", cid->psb);
		return ((char *) NULL);
	}
	res = (char *) malloc (strlen (cid->idval.rsn) + strlen (rwaddr) + 3);
	if (res == NULL)
		FatalError ("System out of string space in MakeRSCall ()", (char *) NULL);
	res = strcpy (res, "$>");	/* construct the call string */
	res = strcat (res, cid->idval.rsn);
	res = strcat (res, rwaddr);
	return (res);
}


/*
 *	MakeField () -- Construct and return the cf string format for a
 *			field variable.  The match count (count), an optional
 *			class (class), and a match repetition flag (fstar)
 *			are used to determine what type of field string to
 *			construct.
 *
 */
char *
MakeField (count, class, fstar)
register int count;		/* match count (0 or 1) */
register struct he *class;	/* optional class type  */
register short fstar;		/* repetition flag	*/
{
	switch (count) {
		case 0:	  if (class == NULL)	/* any token is valid */
				if (fstar)
					return (Zfield);
				else {
					ErrorReport ("Invalid field type.\n");
					return ((char *) NULL);
				}
			  else {		/* match 0 from class */
				Cfield[1] = '~';
				Cfield[2] = MakeMac (class, ID_CLASS);
				return (Cfield);
			  }
		case 1:	  if (class == NULL)	/* any token is valid */
				if (fstar)
					return (Pfield);
				else
					return (Ofield);
			  else {		/* match 1 from class */
				Cfield[1] = '=';
				Cfield[2] = MakeMac (class, ID_CLASS);
				return (Cfield);
			  }
		default:  ErrorReport ("Invalid field type.\n");
	}
	/*NOTREACHED*/
}
SHAR_EOF
if test 10730 -ne "`wc -c strops.c`"
then
echo shar: error transmitting strops.c '(should have been 10730 characters)'
fi
cat << \SHAR_EOF > symtab.c
/*	$Header: /usr/src/local/etc/ease/RCS/symtab.c,v 1.2 85/10/29 23:46:48 jss Exp $	*/

/*
 *  	symtab.c   -- Contains Ease Translator symbol table routines.
 *
 *  	author     -- James S. Schoner, Purdue University Computing Center,
 *				        West Lafayette, Indiana  47907
 *
 *  	date       -- July 9, 1985
 *
 *	Copyright (c) 1985 by Purdue Research Foundation
 *
 *	All rights reserved.
 *
 */

#include <stdio.h>
#include <ctype.h>
#include "symtab.h"

#define ERRORMAILER "error"		/* predefined error mailer name */

extern void FatalError (),
	    PrintWarning ();

struct he *LookupSymbol ();

struct Defmac {				/* predefined macro struct def  */
	char *macname;
	char  macrep;
};

struct he *SymTab[SST];			/* hash table base array        */
static struct Defmac MacDefs[] = {	/* predefined macros	        */
			{"m_smtp",	'e'},
			{"m_oname",	'j'},
			{"m_ufrom",	'l'},
			{"m_daemon",	'n'},
			{"m_addrops",	'o'},
			{"m_defaddr",	'q'},
			{"m_sitename",	'w'},
			{"m_odate",	'a'},
			{"m_adate",	'b'},
			{"m_hops",	'c'},
			{"m_udate",	'd'},
			{"m_saddr",	'f'},
			{"m_sreladdr",	'g'},
			{"m_rhost",	'h'},
			{"m_qid",	'i'},
			{"m_pid",	'p'},
			{"m_protocol",	'r'},
			{"m_shostname", 's'},
			{"m_ctime",	't'},
			{"m_ruser",	'u'},
			{"m_version",	'v'},
			{"m_sname",	'x'},
			{"m_stty",	'y'},
			{"m_rhdir",	'z'},
			{"sentinel",	'\0'}
};


/*
 *	DefScan () -- Scan symbol table to find macros, classes, mailers, 
 *		      and rulesets which have been referenced or declared, but
 *		      not defined.  A warning is printed for each such 
 *		      occurence.  This routine is usually called at the end
 *		      of a successful Ease translation.
 *
 */
void
DefScan ()
{
	register int stindex;		/* symbol table hash index   */
	register struct he *hcsearch;	/* hash chain search pointer */

	for (stindex = 0; stindex < SST; stindex++) {
		if ((hcsearch = SymTab[stindex]) != NULL)
			while (hcsearch != NULL) {
				if ((ISMACRO(hcsearch->idtype) && 
				     isupper(hcsearch->idval.idc)) &&
				     !ISMACRO(hcsearch->idd))
					PrintWarning ("Macro not defined: %s\n", hcsearch->psb);
				if (ISCLASS(hcsearch->idtype) && !ISCLASS(hcsearch->idd))
					PrintWarning ("Class not defined: %s\n", hcsearch->psb);
				if (ISMAILER(hcsearch->idtype) && !ISMAILER(hcsearch->idd))
					PrintWarning ("Mailer not defined: %s\n", hcsearch->psb);
				if (ISRULESET(hcsearch->idtype) && !ISRULESET(hcsearch->idd))
					PrintWarning ("Ruleset not defined: %s\n", hcsearch->psb);
				hcsearch = hcsearch->phe;
			}
	}
}
				     

/*
 *	InitSymbolTable () -- Invoked by main () to initialize the symbol table.
 *
 */
void
InitSymbolTable ()
{
	int i;

	for (i = 0; i < SST; i++)		/* initialize base array */
		SymTab[i] = NULL;
}


/*
 *	PreLoad () -- Invoked by main () to preload special macro names 
 *		      and mailer declarations.
 *
 */
void
PreLoad ()
{
	struct Defmac *macptr;
	struct he     *symptr;

	/* preload special (lower-case) macros */
	for (macptr = &MacDefs[0]; (*macptr).macrep != '\0'; macptr++) {
		symptr = LookupSymbol ((*macptr).macname);
		symptr->idtype |= ID_MACRO;
		symptr->idval.idc = (*macptr).macrep;
	}

	/* preload error mailer declaration */
	symptr = LookupSymbol (ERRORMAILER);
	symptr->idtype |= ID_MAILER;
	symptr->idd |= ID_MAILER;
}
	

/*
 *	LookupSymbol () -- Returns a pointer to the hash entry already 
 *			   existing, or newly created, which corresponds 
 *			   to string sb.
 *
 */
struct he *
LookupSymbol (sb)
char sb[];			/* string buffer containing identifier */
{
	struct he *phe;		/* hash entry search pointer  */
	int	  hc;		/* hash code of sb identifier */

	phe = SymTab[hc = HashCode (sb)];
	while (phe != NULL)			/* find hash entry for sb */
		if (!strcmp (phe->psb, sb))
			return (phe);
		else
			phe = phe->phe;
	/* make new symbol table entry */
	if ((phe = (struct he *) malloc (sizeof (struct he))) == NULL)
		FatalError ("System out of space in LookupSymbol ()", (char *) NULL);
	if ((phe->psb = (char *) malloc (strlen (sb) + 1)) == NULL)
		FatalError ("System out of space in LookupSymbol ()", (char *) NULL);
	strcpy (phe->psb, sb);
	phe->idval.idc = '\0';
	phe->idtype = ID_UNTYPED;
	phe->idd = ID_UNTYPED;
	phe->phe = SymTab[hc];
	return (SymTab[hc] = phe);
}


/*
 *	RemoveSymbol () -- Removes the symbol table entry phe from the 
 *			   symbol table.
 *
 */
void
RemoveSymbol (phe)
struct he *phe;	   /* pointer to hash entry to be removed from symbol table */
{
	int hc;	   		/* hash code of entry phe       */
	struct he *sphe;	/* search pointer for entry phe */

	if (phe == NULL)
		return;
	else {			/* search and remove entry phe  */
		sphe = SymTab[hc = HashCode (phe->psb)];
		free (phe->psb);
		if (sphe == phe)
			SymTab[hc] = phe->phe;
		else
			while (sphe != NULL)
				if (sphe->phe == phe) {
					sphe->phe = phe->phe;
					return;
				} else
					sphe = sphe->phe;
	}
}


/*
 *	HashCode () -- Returns the hash code of the string in sb by adding 
 *		       the character values and applying mod by the hash 
 *		       table size.
 *
 */
int
HashCode (sb)
char sb[];
{
	int ccSum = 0;			/* sum of char values in string sb */
	int i;

	for (i = 0; sb[i]; i++)		/* add char codes for sb chars     */
		ccSum += sb[i];
	return (ccSum % SST);		/* return sum mod table size	   */
}
SHAR_EOF
if test 5288 -ne "`wc -c symtab.c`"
then
echo shar: error transmitting symtab.c '(should have been 5288 characters)'
fi
cat << \SHAR_EOF > lexan.l
%{
/*	$Header: /usr/src/local/etc/ease/RCS/lexan.l,v 1.2 85/10/29 23:42:40 jss Exp $	*/

/*
 *	lexan.l -- Lexical Analyzer for EASE.
 *
 *		   Contains code for lex(1) which generates a lexical
 *		   analyzer (lex.yy.c) for Ease, a high-level specification 
 *		   format for sendmail configuration files.
 *
 *	author -- James S. Schoner, Purdue University Computing Center,
 *				    West Lafayette, Indiana  47907
 *
 *	date   -- July 1, 1985
 *
 *	Copyright (c) 1985 by Purdue Research Foundation
 *
 *	All rights reserved.
 *
 */

#include "symtab.h"
#include "lexdefs.h"

#define  LEXnewline '\n'
#define	 LEXeof	    '\0'
#define  MaxFN	    200			/* maximum file name length */

extern struct he *LookupSymbol ();
extern void	  ErrorReport ();

int  Lcount;				/* line counter		    */
char FNbuf[MaxFN];			/* file name buffer	    */
short RMatch  = FALSE;			/* ruleset match flag  	    */

%}

/* lex-specific extensions */
%e 1100
%p 3700
%n 500

%%
	int INch;			/* any input character */

[ \t\f]+			; 	/* discard whitepsace  */
[\n]				Lcount++;
^\#[ \t]*[0-9]+[ \t]*\".*\"[ \t]*$	{
			        sscanf (yytext, "%*c%d%s", &Lcount, FNbuf);
			        INch = input ();
			        }
match				return (MATCH);
in				return (IN);
bind				return (BIND);
define				return (DEFINE);
macro				return (MACRO);
class				return (CLASS);
options				return (OPTIONS);
precedence			return (PRECEDENCE);
trusted				return (TRUSTED);
header				return (HEADER);
ruleset				return (RULESET);
mailer				return (MAILER);
host				return (HOST);
user				return (USER);
hostnum				return (HOSTNUM);
if				return (IF);
retry				return (RETRY);
next				return (NEXT);
return				return (RETURN);
resolve				return (RESOLVE);
for				return (FOR);
field				return (FIELD);
concat				return (CONCAT);
ifset				return (IFSET);
canon				return (CANON);
readclass			return (READCLASS);
Path				return (MPATH);
Flags				return (MFLAGS);
Sender				return (MSENDER);
Recipient			return (MRECIPIENT);
Argv				return (MARGV);
Eol				return (MEOL);
Maxsize				return (MMAXSIZE);
o_alias				return (AAOPT);
o_ewait				return (AOPT);
o_bsub				return (BBOPT);
o_qwait				return (COPT);
o_delivery			return (DOPT);
d_interactive			return (DOPTI);
d_background			return (DOPTB);
d_queue				return (DOPTQ);
o_rebuild			return (DDOPT);
o_handling			return (EOPT);
h_print				return (EOPTP);
h_exit				return (EOPTE);
h_mail				return (EOPTM);
h_write				return (EOPTW);
h_mailz				return (EOPTZ);
o_tmode				return (FFOPT);
o_usave				return (FOPT);
o_gid				return (GOPT);
o_fsmtp				return (HHOPT);
o_skipd				return (IOPT);
o_slog				return (LLOPT);
o_rsend				return (MOPT);
o_dnet				return (NNOPT);
o_hformat			return (OOPT);
o_qdir				return (QQOPT);
o_tread				return (ROPT);
o_flog				return (SSOPT);
o_safe				return (SOPT);
o_qtimeout			return (TTOPT);
o_timezone			return (TOPT);
o_dmuid				return (UOPT);
o_verbose			return (VOPT);
o_wizpass			return (WWOPT);
o_loadq				return (XOPT);
o_loadnc			return (XXOPT);
f_ffrom				return (FFLAG);
f_rfrom				return (RFLAG);
f_noreset			return (SSFLAG);
f_noufrom			return (NFLAG);
f_locm				return (LFLAG);
f_strip				return (SFLAG);
f_mult				return (MFLAG);
f_from				return (FFFLAG);
f_date				return (DDFLAG);
f_mesg				return (MMFLAG);
f_full				return (XFLAG);
f_return			return (PPFLAG);
f_upperu			return (UFLAG);
f_upperh			return (HFLAG);
f_arpa				return (AAFLAG);
f_ufrom				return (UUFLAG);
f_expensive			return (EFLAG);
f_dot				return (XXFLAG);
f_llimit			return (LLFLAG);
f_retsmtp			return (PFLAG);
f_smtp				return (IIFLAG);
f_addrw				return (CCFLAG);
[A-Za-z][A-Za-z0-9_-]*		{
				/* store identifiers in symbol table */
				yylval.phe = LookupSymbol (yytext);
				return (IDENT);
				}
["]((\\\n)|(\\\")|[^"\n])*	{
				if ((INch = input()) == LEXnewline) {
					ErrorReport ("End of line in string.\n");
					unput (INch);
				}
				yylval.psb = (char *) malloc (strlen (yytext) + 1);
				strcpy (yylval.psb, yytext + 1);
				return (SCONST);
				}
[0][0-7]*			{
				sscanf (yytext, "%o", &yylval.ival);  /* octal constant */
				return (ICONST);
				}
[-]?[1-9][0-9]*			{
				yylval.ival = atoi (yytext);
				return (ICONST);
				}
"="				return (ASGN);
","				return (COMMA);
"{"				return (LBRACE);
"}"				return (RBRACE);
"("				return (LPAREN);
")"				return (RPAREN);
";"				return (SEMI);
"$"				return (DOLLAR);
":"				return (COLON);
"*"				return (STAR);
"/*"				{
				/* eat C comments */
				INch = input ();
				while ((INch != '*') || 
				      ((INch = input ()) != '/')) {
					if (INch == LEXnewline)
						Lcount++;
					else
						if (INch == LEXeof) {
							ErrorReport ("End of file in comment.\n");
							break;
						}
					if (INch != '*')
						INch = input ();
				}
				}
[\\]?.				{
				if (RMatch) {	/* in rulesets, return literal character */
					yylval.ival = (yytext[0] == '\\') ? yytext[1] : yytext[0];
					return (SEPCHAR);
				} else {
					ErrorReport ("Illegal delimiter character");
					printf (": (octal code) \\%03o\n", *yytext);
				}
				}
%%
SHAR_EOF
if test 5031 -ne "`wc -c lexan.l`"
then
echo shar: error transmitting lexan.l '(should have been 5031 characters)'
fi
cat << \SHAR_EOF > symtab.h
/*	$Header: /usr/src/local/etc/ease/RCS/symtab.h,v 1.2 85/10/29 23:47:47 jss Exp $	*/

/*
 *	symtab.h    -- Definitions related to the "et" symbol table. 
 *
 *	author	    -- James S. Schoner, Purdue University Computing Center,
 *					 West Lafayette, Indiana  47907
 *
 *	date	    -- July 1, 1985
 *
 *	Copyright (c) 1985 by Purdue Research Foundation
 *
 *	All rights reserved.
 *
 */

#define TRUE      1
#define FALSE     0
#define SST       101		/* size of hash table (symbol table) 	     */
#define RSNMAX    5		/* size of a ruleset number character buffer */
#define VALRSNMAX 9999		/* max value of ruleset number		     */


/* identifier types */
#define ID_UNTYPED 0
#define ID_MACRO   01
#define ID_CLASS   02
#define ID_RULESET 04
#define ID_FIELD   010
#define ID_PREC	   020
#define ID_MAILER  040

/* identifier type macros */
#define ISTYPED(x) (x|ID_UNTYPED)
#define ISMACRO(x) (x&ID_MACRO)
#define ISCLASS(x) (x&ID_CLASS)
#define ISRULESET(x) (x&ID_RULESET)
#define ISFIELD(x) (x&ID_FIELD)
#define ISPREC(x) (x&ID_PREC)
#define ISMAILER(x) (x&ID_MAILER)

/* block definition types */
enum bdefs {def_macro, def_class, def_option, def_prec, def_trusted, 
	    def_header, def_mailer, def_ruleset};

/* option types */
enum opts {opt_A, opt_a, opt_B, opt_c, opt_D, opt_d, opt_e, opt_F, opt_f, 
	   opt_g, opt_H, opt_i, opt_L, opt_m, opt_N, opt_o, opt_Q, opt_r, 
	   opt_S, opt_s, opt_T, opt_t, opt_u, opt_v, opt_W, opt_x, opt_X, 
	   d_opt_i, d_opt_b, d_opt_q,
	   e_opt_p, e_opt_e, e_opt_m, e_opt_w, e_opt_z};

/* flag types */
enum flgs {flg_f, flg_r, flg_S, flg_n, flg_l, flg_s, flg_m, flg_F, flg_D,
	   flg_M, flg_x, flg_P, flg_u, flg_h, flg_A, flg_U, flg_e, flg_X,
	   flg_L, flg_p, flg_I, flg_C};

/* mailer parameters */
enum mats {mat_path, mat_flags, mat_sender, mat_recipient, mat_argv, 
	   mat_eol, mat_maxsize};

struct he {	/* hash entry structure for symbol table node 	*/
	unsigned   idtype;	/* identifier type 		*/
	unsigned   idd;	  	/* identifier definition flag 	*/
	char      *psb;		/* identifier string buffer 	*/
	union {
		char rsn[RSNMAX]; 	/* ruleset number   	      */
		int prec;	  	/* precedence value 	      */
		char idc;		/* one char id representation */
		char *fstring;    	/* field string     	      */
	} idval;
	struct he *phe;		/* next hash entry 		*/
};
SHAR_EOF
if test 2309 -ne "`wc -c symtab.h`"
then
echo shar: error transmitting symtab.h '(should have been 2309 characters)'
fi
cat << \SHAR_EOF > Makefile
# Makefile for Ease Translator (et).
#
#	$Header: /usr/src/local/etc/ease/RCS/Makefile,v 1.4 85/10/29 22:57:06 jss Exp $
#
#	James S. Schoner, Purdue University Computing Center,
#			  West Lafayette, Indiana  47907
#
#	Copyright (c) 1985 by Purdue Research Foundation
#
#	All rights reserved.
#

INCLUDE =

DEST = /usr/local/etc

OWNER = binary
GROUP = system
MODE = 751

DEFS =
CFLAGS = -O ${DEFS} ${INCLUDE}

LP = lpr
LPFLAGS = -J"Ease Source"

HDR = symtab.h
SRC = main.c emitcf.c errors.c idman.c strops.c symtab.c
LST = Makefile lexan.l parser.y ${HDR} ${SRC}
DEP = y.tab.c lex.yy.c ${SRC}
OBJ = y.tab.o lex.yy.o main.o emitcf.o errors.o idman.o strops.o symtab.o

all: et

et: ${OBJ}
	cc ${CFLAGS} -o et ${OBJ} -ll

clean: FRC
	rm -f et *.o lex.yy.c y.tab.c y.output yacc.acts yacc.tmp \
	      lexdefs.h y.tab.h errs Makefile.bak

depend: ${DEP} ${HDR}
	maketd -a ${DEP}

install: et FRC
	install -c -m ${MODE} -o ${OWNER} -g ${GROUP} -s et ${DEST}

lint:   ${DEP} symtab.h FRC
	lint -hxn ${DEP}

print:  ${LST} FRC
	@pr -f ${LST} | ${LP} ${LPFLAGS}

spotless: clean FRC
	rcsclean ${LST}

lexdefs.h y.tab.c: parser.y
	yacc -d parser.y
	-(cmp -s y.tab.h lexdefs.h || cp y.tab.h lexdefs.h)

lex.yy.c: lexan.l
	lex lexan.l

${HDR} ${SRC} lexan.l parser.y:
	co $@

FRC:
	

# DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
# Dependencies generated at: Thu Oct 17 14:55:17 EST 1985

emitcf.o: symtab.h
emitcf.o: /usr/include/stdio.h
emitcf.o: emitcf.c
errors.o: /usr/include/stdio.h
errors.o: errors.c
idman.o: symtab.h
idman.o: /usr/include/stdio.h
idman.o: idman.c
lex.yy.o: lexdefs.h
lex.yy.o: symtab.h
lex.yy.o: /usr/include/stdio.h
lex.yy.o: lex.yy.c
main.o: /usr/include/stdio.h
main.o: main.c
strops.o: symtab.h
strops.o: /usr/include/stdio.h
strops.o: /usr/include/strings.h
strops.o: strops.c
symtab.o: symtab.h
symtab.o: /usr/include/ctype.h
symtab.o: /usr/include/stdio.h
symtab.o: symtab.c
y.tab.o: symtab.h
y.tab.o: /usr/include/stdio.h
y.tab.o: y.tab.c

# DO NOT ADD ANYTHING HERE - it will go away.
SHAR_EOF
if test 2016 -ne "`wc -c Makefile`"
then
echo shar: error transmitting Makefile '(should have been 2016 characters)'
fi
chdir ..
#	End of shell archive
exit 0



More information about the Mod.sources mailing list