[comp.sources.misc] v07i017: Big Banner program, 1/4

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (06/11/89)

Posting-number: Volume 7, Issue 17
Submitted-by: jbayer@ispi.UUCP
Archive-name: banner/part01

[Okay, so I typoed.  -mm is USG (I ought to know, I'm using it daily) and
-me is BSD.  However, contrary to popular opinion, -ms is not a standard
package on USG systems -- although most companies that provide nroff/troff
also provide -ms, it doesn't seem to be part of vanilla System III/V.  ++bsa]

This program prints large banners on any standard printer that is
capable of printing at least 132 characters across.  

This is a Shareware program.



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 4)."
# Contents:  MANIFEST Makefile README banner.c banner.h banner.mak
#   data.ad egetopt.c
# Wrapped by cdbms@ispi on Fri Jun  9 18:09:06 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(455 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	This shipping list
X Makefile                   1	
X README                     1	
X banner.c                   1	
X banner.h                   1	
X banner.mak                 1	
X data.aa                    4	
X data.ab                    2	
X data.ac                    3	
X data.ad                    1	
X egetopt.c                  1	
END_OF_FILE
if test 455 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1543 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#/************************************************************************
X# *									*
X# *		written by 	Jonathan B. Bayer			*
X# *				500 Oakwood Ave.			*
X# *				Roselle Park, NJ   07204		*
X# *									*
X# *									*
X# *		Copyright, 1989						*
X# *									*
X# *		Released June, 1989 as shareware			*
X# *									*
X# *		A payment of $ 15 is requested if you find this		*
X# *		program useful.	 This will register your copy and	*
X# *		ensure that you will be notified of any new versions.	*
X# *		It will also entitle you to receive the font editor	*
X# *		when it is released.					*
X# *									*
X# ************************************************************************/
X#
X#
X# uncomment the following line if you want all the character tables stored
X# with the program instead of in data files.
XOPTIONS = -DRESIDENT
X
XCFLAGS = $(OPTIONS) -Mm2
XLFLAGS = -lcurses -ltermcap
XSRCS = banner.c egetopt.c data.c
XSHAR_SRCS = banner.c egetopt.c data.a*
XOBJS = banner.o egetopt.o data.o
XMAKES = Makefile banner.mak
XHEADERS = banner.h
XCC = cc
X
Xall:	big.banner save
X
Xbig.banner:	$(OBJS)
X	$(CC) $(CFLAGS) $(OBJS) $(LFLAGS) -o big.banner
X
Xbanner.o:	banner.c banner.h
X
Xegetopt.o:	egetopt.c
X
Xdata.o:		data.c banner.h
X
Xsave.o:		save.c banner.h
X
Xsave:		save.o
X	$(CC) $(CFLAGS) -DRESIDENT data.c -c
X	$(CC) $(CFLAGS) save.o data.o $(LFLAGS) -o save
X	rm -f data.o
X
Xshar:	;
X	split -750 data.c data.
X	makekit -o MANIFEST $(SHAR_SRCS) $(MAKES) $(HEADERS) README
X	rm -f data.a*
X
Xdata.c:	;
X	cat data.a* > data.c
X
Xclean:
X	rm -f *.o
X
Xclobber:
X	rm -f *.o big.banner save
X	
END_OF_FILE
if test 1543 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(5288 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X                          B I G . B A N N E R
X
X
X	written by 	Jonathan B. Bayer
X			500 Oakwood Ave.
X			Roselle Park, NJ   07204
X			jbayer@ispi.uucp  or ...uunet!ispi!jbayer
X 			
X 
X 	Copyright, 1989
X 
X 	Released June, 1989 as shareware
X 
X 	A payment of $ 15 is requested if you find this
X 	program useful.  This will register your copy and
X 	ensure that you will be notified of any new versions. 
X	It will also entitle you to receive the font editor when
X	it is released.
X
X
X
XThis program prints large banners on any standard printer that is
Xcapable of printing at least 132 characters across.  It consists of the
Xfollowing files:
X
X	banner.h	header file 
X	banner.c	Main program
X	data.c		data file containing layouts of characters
X	save.c		supplemental program which creates data files
X			containing the character layout information.
X
X
X	egetopt.c	A public-domain version of the standard getopt()
X			routines.  This version was originally written
X			by Keith Bostic, and enhanced by Lloyd Zusman. 
X			I do not claim any copyright on this.  It is
X			supplied as a convenience to those systems that
X			do not have the getopt() routines.  However,
X			please note that I do take advantage of a few of
X			the enhancements that are in it.
X
XThis program has been tested to compile and execute on the following
Xsystems and compilers:
X
XSCO Xenix 386, 2.3.1, in all memory models.
X
XMS-DOS, Microsoft C 5.1 and Quick C, in all memory models, with the
Xansi.sys driver installed.
X
X
XIt should compile on most systems and under most compilers.  There is
Xvery little system-dependent code.
X
XTo compile on Unix, type:
X
X	make
X
XTo compile on DOS, type
X
X	make banner.mak
X
X
XOn MS-DOS the program has screen codes hard-coded in for the ansi.sys
Xdriver.  On Xenix it uses termcap.  However, if you would like to have
Xthe program use the hard-coded screen codes instead of termcap simply
Xdefine -DMSDOS during the compile.
X
XThe program has two methods of obtaining the character layouts.  They are:
X
X1.  All the character tables are stored in memory along with the
X    program.  This has the advantage of slightly faster execution of
X    the program.  It has two disadvantages.  One is that it takes up
X    more space, the second is that it is more difficult to add new
X    character tables.
X
X2.  The program stores the character layouts in data files on the disk. 
X    The data files are created with the supplemental program "save",
X    which saves the files in the appropriate format for the program. 
X    The files are stored in the directory "LIB_DIR", which is set up to
X    be "/usr/local/lib".  It is defined in "banner.h".  To activate this
X    option define the option "-DRESIDENT" in the makefile.
X
X
XThe program has two modes of operation.  One is command-line driven, the
Xother is prompted.  To run the program with menus you simply have to
Xexecute it.  The menus are simple, and easy to understand.
X
XTo run the program from the command line the following options are
Xavailable:
X 									
X		-m 	The message to be printed.  If there are spaces  
X			then the message should be enclosed inside quotes  
X			Optionally, you can put the message at the end  
X			of the options without the -m in front of it.  
X			A message at the end does not need the quotes if  
X			there is to be only one space between each word. 
X 
X		-f	The font number.  Current fonts are:  
X				1.	Gothic  
X				2.	Roman  
X				3.	Computer 
X 
X		-p	The print destination.  The default destination is  
X			the standard output. 
X 
X		-o	The number of overstrikes.  The program can support  
X			three overstrikes.  The first line printed uses  
X			an \"X\".  The second line prints an \"O\" on top of  
X			the first line, and the third line prints an \"@\".  
X
X
XDOS users can replace the "-" with a "/" before the option.  If the
Xprint destination is not specified then the output will be sent to the
Xstandard output.
X
X(note to novices:  The standard output can be redirected to a file or a
Xdevice by using the redirection symbol ">".  This works on both DOS and
XUnix.  For example,
X
X	big.banner -f 1 -o 2 -m "Happy Birthday" > PRN
X
Xwill print the message to the standard output which has been redirected
Xto PRN.  Therefore, it will print directly on the printer.)
X
XNOTE:  80 COLUMN PRINTERS WILL HAVE TO BE SET TO A PITCH SETTING OF AT
XLEAST 15 OR GREATER.  Also, the vertical motion index should also be
Xadjusted to between 9 and 10 lines per inch.
X
X----------------------------------------------------------------------------
X
XFuture enhancements will include smoothing the Roman and Computer fonts.
XThe best font is currently the Gothic font.  The Roman and Computer
Xfonts are block characters, and some of the characters don't look too
Xgood.  There will also be a font editor if there is interest (read that
Xto mean that if enough people register I will release the font editor to
Xthe registered people only).
X
XAnother enhancement will be to support an initialization string based on
Xthe printer type.  80 column printers have to be shifted into 15 pitch
Xor greater in order to print correctly.  I would like to create a
Xdatabase of printer definitions that would enable the user to either
Xcompile in, or specify at run time what printer they are using.  This
Xwould let the program initialize the printer properly, and reset it at
Xthe end.
X
END_OF_FILE
if test 5288 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'banner.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'banner.c'\"
else
echo shar: Extracting \"'banner.c'\" \(11113 characters\)
sed "s/^X//" >'banner.c' <<'END_OF_FILE'
X/************************************************************************
X *									*
X *		written by 	Jonathan B. Bayer			*
X *				500 Oakwood Ave.			*
X *				Roselle Park, NJ   07204		*
X *									*
X *									*
X *		Copyright, 1989						*
X *									*
X *		Released June, 1989 as shareware			*
X *									*
X *		A payment of $ 15 is requested if you find this		*
X *		program useful.	 This will register your copy and	*
X *		ensure that you will be notified of any new versions.	*
X *		It will also entitle you to receive the font editor	*
X *		when it is released.					*
X *									*
X ************************************************************************/
X
X
X
X/************************************************************************
X *									*
X *	Options:							*
X *									*
X *		-m "message"						*
X *		-f font #						*
X *		-p print destination					*
X *		-o # overstrikes					*
X *									*
X *									*
X ************************************************************************/
X
X
X#include	<stdio.h>
X#include	<string.h>
X#include	<malloc.h>
X
X#include	"banner.h"
X
X#ifdef	RESIDENT
Xlpat_type	*lpat;
Xpsub_type	*psub;
X#else
Xlpat_ar		lpat;
Xpsub_ar		psub;
X#endif
X
Xstdstr		char_set, st;
Xlongstr		blank, line1, line2, line3;
Xchar		*msg;
Xchar		ix, io, ia;
Xint		l, l1, x, num, npos, nnpos, ips;
XFILE		*pr;
X
Xchar		*prog_name;
Xchar		*in_msg = NULL, *p_dest = NULL;
Xint		font = -1, overstrikes = -1;
X
X
Xextern psub_ar computer_p;
Xextern lpat_ar computer_l;
Xextern psub_ar roman_p;
Xextern lpat_ar roman_l;
Xextern psub_ar gothic_p;
Xextern lpat_ar gothic_l;
X
X
X#ifdef	MSDOS
X
X	/* simple routines to replace curses functions */
X
Xvoid	refresh()	/* null function on DOS */
X{
X} /* refresh */
X
X
X
Xvoid	initscr()
X{
X} /* initscr */
X
X
Xvoid	endwin()
X{
X} /* endwin */
X
X
X
Xvoid	raw()
X{
X} /* raw */
X
X
X
Xvoid	nl()
X{
X} /* nl */
X
X
X
Xint	addstr(st)
Xchar	*st;
X{
X	printf(st);
X	fflush(stdout);
X} /* addstr */
X
X
X
Xvoid	clear()
X{
X	printf("\033[2J");
X	fflush(stdout);
X} /* clear */
X
X
X
Xint	mvaddstr(x,y,st)
Xint	x,y;
Xchar	*st;
X{
X	printf("\033[%02d;%02dH",x , y);
X	addstr(st);
X} /* mvaddstr */
X
X
X
Xint	getstr(st)
Xchar	*st;
X{
X	gets(st);
X} /* getstr */
X
X#endif /* MSDOS */
X
X
Xvoid	help()
X{
X	printf("%s: [-m message] [-f font #] [-p print destination] [-o # overstrikes]\n", prog_name);
X	printf("\n\n");
X	printf("Type the program name by itself to be prompted for all the options\n\n");
X	printf("Options:	-m 	The message to be printed.  If there are spaces\n");
X	printf("			then the message should be enclosed inside quotes\n");
X	printf("			Optionally, you can put the message at the end\n");
X	printf("			of the options without the -m in front of it.\n");
X	printf("			A message at the end does not need the quotes if\n");
X	printf("			there is to be only one space between each word.\n\n");
X	printf("		-f	The font number.  Current fonts are:\n");
X	printf("				1.	Gothic\n");
X	printf("				2.	Roman\n");
X	printf("				3.	Computer\n\n");
X	printf("		-p	The print destination.  The default destination is\n");
X	printf("			the standard output.\n\n");
X	printf("		-o	The number of overstrikes.  The program can support\n");
X	printf("			three overstrikes.  The first line printed uses\n");
X	printf("			an \"X\".  The second line prints an \"O\" on top of\n");
X	printf("			the first line, and the third line prints an \"@\".\n\n");
X
X	exit(0);	
X}
X
X
Xvoid	f_error(st1,st2)
Xchar 	*st1, *st2;
X{
X	fprintf(stderr,"file error %s in file %s",st2, st1);
X	if (!in_msg)
X		endwin();
X	exit(1);
X} /* f_error */
X
X
X
Xvoid vtb(x)
Xint x;
X{
X	int x1;
X
X	if (x == 0)
X		fprintf(pr,"\r");
X	{
X		for (x1 = 1; x1 <= x; ++x1)
X			fprintf(pr,"\n");
X		x1--;
X	}
X} /* VTB */
X
X
X
Xvoid	fillchar(st, num, ch)
Xregister char	*st;
Xregister int	num;
Xchar		ch;
X{
X	while (num--) *st++ = ch;
X} /* FILLCHAR */
X
X
X
Xvoid do_it()
X{
X
X	if (in_msg) {
X		l = 0;
X		msg = in_msg;
X	} else {
X		l = 9999;
X		msg = (char *) malloc(512);
X	}
X	do
X	{
X		l = l + 1;
X		if (l > strlen(msg))
X		{
X			if (in_msg) exit(0);
X			l = 1;
X			clear();
X			addstr("Enter the message, <CR> when done.\n");
X			refresh();
X			getstr(msg);
X			if (((((strcmp(msg,"END") == 0)) || ((strcmp(msg,"end") == 0))) || ((strcmp(msg,"") == 0))))
X				return;
X		}
X		do
X		{
X			l1 = l;
X			if ( (msg[(l)-1]) == ' ') {
X				l = l + 1;
X				vtb(20);
X					/* SPACE IS 28 LINES WIDE, 20 ADDED
X                                                     HERE, AND 8 LATER */
X			}
X		}      while (l1 != l);
X
X		num = msg[l-1];
X		
X#ifdef	RESIDENT
X		ips = *(psub +num - 1);
X#else
X		ips = psub[num - 1];
X#endif
X		
X			/* GET START POSITION FROM PSUB */
X			
X		if (ips > 0)
X		{
X			vtb(5);
X			do
X			{
X				npos = 0;
X				if ((strcmp(char_set,"gothic") != 0))
X					npos = 1;
X				strcpy(line1,blank);
X				strcpy(line2,blank);
X				strcpy(line3,blank);
X				do
X				{
X#ifdef	RESIDENT
X					num = *(lpat+ips - 1);
X					npos = npos + num;
X					num = *(lpat+ips);
X#else
X					num = lpat[ips - 1];
X					npos = npos + num;
X					num = lpat[ips];
X#endif
X
X					if (npos - 132 <= 0)
X					{
X						nnpos = npos + num - 1;
X						fillchar(&(line1[(npos)-1]),num,ix);
X						fillchar(&(line2[(npos)-1]),num,ia);
X						fillchar(&(line3[(npos)-1]),num,io);
X						npos = nnpos;
X						ips = ips + 2;
X					}
X				}            while (!(npos - 132 > 0));
X				line1[nnpos + 1] = 0;
X				line2[nnpos + 1] = 0;
X				line3[nnpos + 1] = 0;
X				
X				fprintf(pr,"%s",line1);
X				if (overstrikes > 1)
X				{
X					vtb(0);
X					fprintf(pr,"%s",line2);
X					if (overstrikes > 2)
X					{
X						vtb(0);
X						fprintf(pr,"%s",line3);
X					}
X				}
X				vtb(1);
X				ips = ips + 1;
X			}         while (!(num - 139 >= 0));
X		}
X		if (ips == 0)
X		{
X			vtb(8);
X		}
X	}   while (1);
X} /* DO_IT */
X
X
X
Xvoid load_data()
X{
X#ifndef	RESIDENT
XFILE 	*f_lpat;
XFILE	*f_psub;
X#endif
Xint	x, x1;
X
X	if (!in_msg) do {
X		clear();
X		mvaddstr(6,5,"Character Set selection");
X		mvaddstr(10,5,"1.  Gothic letters");
X		mvaddstr(12,5,"2.  Roman letters");
X		mvaddstr(14,5,"3.  Computer letters");
X		mvaddstr(18,5,"Enter the character set number, 0 to exit:");
X		refresh();
X		getstr(st);
X		font = -1;
X		if (strcmp(st,"0") == 0)
X			font = 0;
X		if (strcmp(st,"1") == 0)
X			font = 1;
X		if (strcmp(st,"2") == 0)
X			font = 2;
X		if (strcmp(st,"3") == 0)
X			font = 3;
X		if (font == 0) {
X			endwin();
X			fclose(pr);
X			exit(0);
X		}
X	} while (font == -1);
X#ifdef	RESIDENT
X	switch (font) {
X	case 1:
X		strcpy(char_set,"gothic");
X		lpat = gothic_l;
X		psub = gothic_p;
X		break;
X	case 2:
X		strcpy(char_set,"roman");
X		lpat = roman_l;
X		psub = roman_p;
X		break;
X	case 3:
X		strcpy(char_set,"computer");
X		lpat = computer_l;
X		psub = computer_p;
X		break;
X	}
X#else
X	strcpy(char_set, LIB_DIR);
X	switch (font) {
X	case 1:
X		strcat(char_set,"gothic");
X		break;
X	case 2:
X		strcat(char_set,"roman");
X		break;
X	case 3:
X		strcat(char_set,"computer");
X		break;
X	}
X
X	strcat(char_set,".l");
X	if ( (f_lpat = fopen(char_set,open_flag)) == NULL) f_error(char_set,"opening");
X	if (fread(lpat,1,MAX_LPAT_AR,f_lpat) != MAX_LPAT_AR) f_error(char_set,"reading");
X	fclose(f_lpat);
X
X	char_set[strlen(char_set) - 1] = 'p';
X
X	if ((f_psub = fopen(char_set,open_flag)) == NULL) f_error(char_set,"opening");
X	if (fread(psub, 2, MAX_PSUB_AR,f_psub) != MAX_PSUB_AR) f_error(char_set,"reading");
X	fclose(f_psub);
X
X#endif
X
X} /* LOAD_DATA */
X
X
X
Xvoid center(x, st)
Xint x;
Xstdstr st;
X{
X	mvaddstr(x,40 - (strlen(st) / 2),st);
X} /* CENTER */
X
X
X
Xvoid title_page()
X{
X	char st[(80)+1];
X
X	clear();
X	center(0,"Welcome to the BANNER PRINTER,  V. 1.00");
X	center(2,"Written by Jonathan B. Bayer");
X	center(4,"Copyright 1989");
X	center(7,"This program is released to the");
X	center(8,"Public Domain with the following restrictions:");
X	center(10,"This title page must not be changed in any manner.");
X	center(11,"All associated files must be passed along with the program.");
X	center(12,"No money other than a four dollar copying charge may to be collected.");
X	center(13,"Users are encouraged to copy and pass this program along to their friends.");
X	center(16,"If you find it useful you are requested to register it by sending");
X	center(17,"fifteen dollars ($ 15.00) to:");
X	center(19,"Jonathan B. Bayer       ");
X	center(20,"500 Oakwood Ave.        ");
X	center(21,"Roselle Park, NJ   07204");
X	center(22,"If you have any comments or suggestions send a message to:");
X	center(23,"UUCP            ...ispi!jbayer          jbayer@ispi.UUCP");
X	refresh();
X	getstr(st);
X} /* TITLE_PAGE */
X
X
X
Xmain (argc,argv)
Xint argc;
Xchar *argv[];
X{
Xextern char	*optstart;
Xextern int	opterr, optind;
Xextern int	egetopt();
Xextern char	*optarg;
X
Xint	c;
X
X
X	prog_name = argv[0];
X	optstart = "-/";
X	opterr = 0;
X
X	while ((c = egetopt(argc, argv,"m:f:p:o:")) != EOF)
X		switch (c) {
X			case 'm':	/* message */
X				in_msg = strdup(optarg);
X				break;
X			case 'f':	/* font # */
X				font = atoi(optarg);
X				break;
X			case 'p':	/* print destination */
X				p_dest = strdup(optarg);
X				break;
X			case 'o':	/* # overstrikes */
X				overstrikes = atoi(optarg);
X				break;
X			case '?':	/* help */
X				help();
X		}
X	if (!in_msg && optind < argc ) {
X		in_msg = (char *)malloc(512);
X		*in_msg = 0;
X		while (optind < argc) {
X			strcat(in_msg, argv[optind++]);
X			if (optind < argc)
X				strcat(in_msg," ");
X		}
X	}
X	
X	if (optind < argc)
X		help();
X
X	if (font != -1 && (font < 1  || font > 3)) {
X		help();
X	} else if (font == -1) font = 1;
X	
X	if (overstrikes != -1 && (overstrikes < 1  || overstrikes > 3)) {
X		help();
X	} else if (overstrikes == -1) overstrikes = 1;
X	
X	
X
X	if (!in_msg) {	
X		initscr();
X		raw();
X		nl();
X
X		title_page();
X		clear();
X#ifdef	MSDOS
X		mvaddstr(0,0,"The normal print destination is PRN.  You can enter a different");
X		mvaddstr(1,0,"destination such as COM1, or even a disk file for later printing.");
X		mvaddstr(3,0,"Enter the print destination, <CR> for <PRN>: ");
X#else
X		mvaddstr(0,0,"The normal destination is a file called PRN.  You can enter a different");
X		mvaddstr(1,0,"file if you like.");
X		mvaddstr(3,0,"Enter the print destination, <CR> for <PRN>: ");
X#endif
X		refresh();
X		getstr(st);
X		if (strlen(st) == 0) strcpy(st,"PRN");
X		p_dest = strdup(st);
X	}
X	if (p_dest) {
X		pr = fopen(p_dest,"w");
X		if (pr == NULL) f_error(st,"opening");
X	} else pr = stdout;
X
X	num = 0;
X	ips = 0;
X	load_data();
X	ix = 'X';
X	io = 'O';
X	ia = '@';
X	*blank = 0;
X	for (x = 1; x <= 131; ++x)
X		strcat(blank," ");
X	x--;
X
X	if (!in_msg) do {
X		clear();
X		center(3,"Overstrikes");
X		center(6,"The program can print on the same line up to three times in order");
X		center(8,"to make the printing darker.  The first line uses an \"X\", the    ");
X		center(10,"second line prints an \"O\" on top of the \"X\", and the third line ");
X		center(12,"prints an \"@\" on top of the other two.                          ");
X		center(15,"The program sends a carrage-return without a line-feed when     ");
X		center(17,"printing the second and third over-strikes.                     ");
X		center(23,"Enter the number of overstrikes you want (between 1 and 3) : ");
X		refresh();
X		getstr(st);
X		overstrikes = 0;
X		if (strcmp(st,"1") == 0)
X			overstrikes = 1;
X		if (strcmp(st,"2") == 0)
X			overstrikes = 2;
X		if (strcmp(st,"3") == 0)
X			overstrikes = 3;
X	} while (overstrikes == 0);
X	if (!in_msg)
X		clear();
X	do_it();
X	if (!in_msg) {
X		clear();
X		refresh();
X		endwin();
X	}
X	fclose(pr);
X	exit(0);
X}
END_OF_FILE
if test 11113 -ne `wc -c <'banner.c'`; then
    echo shar: \"'banner.c'\" unpacked with wrong size!
fi
# end of 'banner.c'
fi
if test -f 'banner.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'banner.h'\"
else
echo shar: Extracting \"'banner.h'\" \(1426 characters\)
sed "s/^X//" >'banner.h' <<'END_OF_FILE'
X/************************************************************************
X *									*
X *		written by 	Jonathan B. Bayer			*
X *				500 Oakwood Ave.			*
X *				Roselle Park, NJ   07204		*
X *									*
X *									*
X *		Copyright, 1989						*
X *									*
X *		Released June, 1989 as shareware			*
X *									*
X *		A payment of $ 15 is requested if you find this		*
X *		program useful.	 This will register your copy and	*
X *		ensure that you will be notified of any new versions.	*
X *		It will also entitle you to receive the font editor	*
X *		when it is released.					*
X *									*
X ************************************************************************/
X
X 
X#ifndef	MSDOS
X#include	<curses.h>
X#define		open_flag	"r"
X#define		write_flag	"w"
X#else
X#define		open_flag	"rb"	/* MS-C, binary mode */
X#define		write_flag	"wb"
X#endif
X
X#ifndef	TRUE
X#define	TRUE	1
X#define FALSE	0
X#endif
X
X#define 	MAX_LPAT_AR		11264
X#define 	MAX_PSUB_AR		280
X
X	/* define a few handy types here */
X#ifdef	M_I386
Xtypedef short		psub_type;
Xtypedef	unsigned char	lpat_type;
Xtypedef psub_type	psub_ar[MAX_PSUB_AR];
Xtypedef lpat_type	lpat_ar[MAX_LPAT_AR];
X#else
Xtypedef	int	psub_type;
Xtypedef	unsigned char	lpat_type;
Xtypedef psub_type	psub_ar[MAX_PSUB_AR];
Xtypedef lpat_type	lpat_ar[MAX_LPAT_AR];
X#endif
X
Xtypedef char longstr[133];	/* a long string */
Xtypedef char stdstr[81];	/* a short string */
X
X#ifndef	RESIDENT
X
X#define	LIB_DIR	"/usr/local/lib/"
X
X#endif
END_OF_FILE
if test 1426 -ne `wc -c <'banner.h'`; then
    echo shar: \"'banner.h'\" unpacked with wrong size!
fi
# end of 'banner.h'
fi
if test -f 'banner.mak' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'banner.mak'\"
else
echo shar: Extracting \"'banner.mak'\" \(1684 characters\)
sed "s/^X//" >'banner.mak' <<'END_OF_FILE'
X#/************************************************************************
X# *									*
X# *		written by 	Jonathan B. Bayer			*
X# *				500 Oakwood Ave.			*
X# *				Roselle Park, NJ   07204		*
X# *									*
X# *									*
X# *		Copyright, 1989						*
X# *									*
X# *		Released June, 1989 as shareware			*
X# *									*
X# *		A payment of $ 15 is requested if you find this		*
X# *		program useful.	 This will register your copy and	*
X# *		ensure that you will be notified of any new versions.	*
X# *		It will also entitle you to receive the font editor	*
X# *		when it is released.					*
X# *									*
X# ************************************************************************/
X#
X# This is a makefile for the Microsoft QuickC  and  C 5.1 version of "banner"
X
X# to store all the character tables in memory instead of in disk files
X# uncomment the following line:
XOPTIONS = -DRESIDENT
X
X# To make a version for debugging or tracing, uncomment this line:
X#CFLAGS = /Zi /Zd
X
X# To make a normal optimized version, uncomment this line:
XCFLAGS = /Ox
X
X# To make a codeview-debuggable executable, uncomment this line:
X#LINKFLAGS = /CODEVIEW /FPa
X
X# This selects what compiler to use
XCC = qcl
X
X# This line should always be uncommented:
XOBJS = banner.obj egetopt.obj data.obj
X
Xegetopt.obj:	egetopt.c
X	$(CC) /c $(CFLAGS) $(OPTIONS)  egetopt.c
X
Xdata.c:
X	copy data.aa+data.ab+data.ac+data.ad data.c
X
Xdata.obj:	data.c
X	$(CC) /c $(CFLAGS) $(OPTIONS)  data.c
X
Xbanner.obj:	banner.c
X	$(CC) /c $(CFLAGS) $(OPTIONS)  banner.c
X
Xbanner.exe:	$(OBJS)
X	$(CC) $(CFLAGS) $(OBJS)
X
Xsave.obj:	save.c
X	$(CC) /c $(CFLAGS) save.c 
X
Xsave.exe:	save.obj
X	$(CC) /c $(CFLAGS) -DRESIDENT data.c
X	$(CC) $(CFLAGS) save.obj data.obj
X
END_OF_FILE
if test 1684 -ne `wc -c <'banner.mak'`; then
    echo shar: \"'banner.mak'\" unpacked with wrong size!
fi
# end of 'banner.mak'
fi
if test -f 'data.ad' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'data.ad'\"
else
echo shar: Extracting \"'data.ad'\" \(7865 characters\)
sed "s/^X//" >'data.ad' <<'END_OF_FILE'
X	10, 255, 45, 10, 255, 45, 10, 255, 45, 10, 255, 45, 10, 255, 0, 
X	10, 18, 28, 255, 0, 10, 18, 28, 255, 0, 10, 18, 28, 255, 0, 
X	10, 18, 28, 255, 0, 10, 18, 28, 255, 0, 10, 9, 10, 18, 10, 
X	255, 0, 10, 9, 10, 18, 10, 255, 0, 10, 9, 10, 18, 10, 255, 
X	0, 10, 9, 10, 18, 10, 255, 0, 10, 9, 10, 18, 10, 255, 0, 
X	10, 9, 10, 255, 0, 10, 9, 10, 255, 0, 10, 9, 10, 255, 0, 
X	10, 9, 10, 255, 0, 10, 9, 10, 255, 0, 10, 9, 10, 255, 0, 
X	10, 9, 10, 255, 0, 10, 9, 10, 255, 0, 10, 9, 10, 255, 0, 
X	10, 9, 10, 255, 9, 46, 255, 9, 46, 255, 9, 46, 255, 9, 46, 
X	255, 9, 46, 255, 139, 9, 10, 18, 19, 255, 9, 10, 18, 19, 255, 
X	9, 10, 18, 19, 255, 9, 10, 18, 19, 255, 9, 10, 18, 19, 255, 
X	9, 19, 18, 10, 255, 9, 19, 18, 10, 255, 9, 19, 18, 10, 255, 
X	9, 19, 18, 10, 255, 9, 19, 18, 10, 255, 9, 10, 9, 10, 9, 
X	10, 255, 9, 10, 9, 10, 9, 10, 255, 9, 10, 9, 10, 9, 10, 
X	255, 9, 10, 9, 10, 9, 10, 255, 9, 10, 9, 10, 9, 10, 255, 
X	9, 10, 18, 19, 255, 9, 10, 18, 19, 255, 9, 10, 18, 19, 255, 
X	9, 10, 18, 19, 255, 9, 10, 18, 19, 255, 9, 19, 18, 10, 255, 
X	9, 19, 18, 10, 255, 9, 19, 18, 10, 255, 9, 19, 18, 10, 255, 
X	9, 19, 18, 10, 255, 139, 36, 10, 255, 36, 10, 255, 36, 10, 255, 
X	36, 10, 255, 36, 10, 255, 18, 19, 9, 19, 255, 18, 19, 9, 19, 
X	255, 18, 19, 9, 19, 255, 18, 19, 9, 19, 255, 18, 19, 9, 19, 
X	255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 
X	255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 
X	255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 
X	255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 
X	255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 255, 9, 10, 45, 10, 
X	255, 139, 0, 73, 255, 0, 73, 255, 0, 73, 60, 8, 117, 36, 232, 
X	215, 40, 138, 14, 86, 6, 254, 201, 42, 205, 115, 6, 2, 205, 138, 
X	233, 50, 201, 232, 106, 42, 10, 201, 116, 9, 50, 192, 232, 206, 42, 
X	254, 201, 117, 247, 195, 60, 9, 117, 52, 232, 156, 40, 128, 249, 9, 
X	116, 14, 128, 249, 10, 232, 27, 253, 25, 147, 191, 130, 6, 232, 9, 
X	187, 161, 130, 6, 232, 158, 42, 161, 132, 6, 232, 152, 42, 161, 134, 
X	6, 232, 146, 42, 161, 136, 6, 232, 140, 42, 161, 138, 6, 233, 134, 
X	42, 232, 13, 0, 131, 62, 86, 6, 1, 116, 3, 233, 121, 42, 233, 
X	129, 42, 232, 88, 40, 58, 14, 80, 6, 232, 219, 252, 44, 147, 59, 
X	6, 82, 6, 124, 7, 59, 6, 84, 6, 127, 1, 195, 232, 215, 252, 
X	45, 255, 54, 202, 5, 255, 54, 202, 5, 184, 0, 0, 232, 125, 44, 
X	232, 252, 44, 255, 54, 202, 5, 232, 115, 44, 232, 126, 44, 232, 54, 
X	47, 232, 66, 7, 93, 161, 78, 6, 137, 70, 254, 93, 198, 70, 255, 
X	3, 232, 243, 46, 232, 4, 46, 1, 255, 149, 117, 204, 143, 6, 208, 
X	5, 80, 232, 187, 6, 88, 195, 232, 79, 5, 232, 219, 46, 232, 236, 
X	45, 1, 255, 149, 117, 242, 195, 198, 6, 230, 5, 255, 191, 251, 5, 
X	51, 210, 138, 5, 10, 192, 116, 17, 60, 46, 117, 2, 139, 215, 71, 
X	60, 92, 117, 239, 139, 223, 51, 210, 235, 233, 11, 210, 116, 2, 139, 
X	250, 129, 255, 55, 6, 232, 57, 252, 92, 160, 240, 5, 50, 228, 254, 
X	6, 240, 5, 199, 5, 46, 48, 177, 10, 246, 241, 5, 48, 48, 137, 
X	69, 2, 198, 69, 4, 0, 184, 14, 13, 232, 162, 41, 184, 255, 255, 
X	232, 178, 41, 185, 13, 0, 138, 7, 232, 181, 41, 67, 226, 248, 232, 
X	229, 42, 232, 45, 42, 160, 183, 2, 80, 255, 54, 59, 6, 255, 54, 
X	218, 5, 255, 54, 220, 5, 255, 54, 222, 5, 255, 54, 224, 5, 255, 
X	54, 226, 5, 255, 54, 106, 6, 255, 54, 128, 6, 128, 62, 183, 2, 
X	0, 117, 5, 198, 6, 183, 2, 2, 161, 218, 5, 43, 6, 220, 5, 
X	1, 6, 222, 5, 51, 192, 163, 128, 6, 163, 224, 5, 163, 226, 5, 
X	128, 62, 183, 2, 1, 116, 19, 180, 60, 51, 201, 186, 251, 5, 30, 
X	7, 232, 117, 168, 232, 156, 251, 92, 163, 59, 6, 51, 192, 163, 218, 
X	5, 163, 220, 5, 232, 20, 45, 1, 40, 150, 232, 159, 251, 16, 255, 
X	54, 212, 5, 255, 54, 218, 5, 80, 232, 52, 252, 88, 198, 6, 111, 
X	6, 255, 232, 154, 0, 232, 63, 252, 232, 85, 42, 89, 90, 85, 161, 
X	218, 5, 43, 193, 10, 192, 116, 7, 50, 192, 232, 14, 41, 235, 240, 
X	93, 137, 70, 242, 1, 6, 224, 5, 131, 22, 226, 5, 0, 161, 212, 
X	5, 43, 194, 137, 22, 212, 5, 59, 6, 128, 6, 114, 3, 163, 128, 
X	6, 232, 107, 41, 232, 240, 44, 31, 150, 116, 151, 128, 62, 183, 2, 
X	1, 116, 9, 180, 62, 139, 30, 59, 6, 232, 245, 167, 139, 22, 128, 
X	6, 143, 6, 128, 6, 143, 6, 106, 6, 143, 6, 226, 5, 143, 6, 
X	224, 5, 143, 6, 222, 5, 143, 6, 220, 5, 143, 6, 218, 5, 143, 
X	6, 59, 6, 88, 162, 183, 2, 3, 22, 212, 5, 139, 30, 106, 6, 
X	161, 218, 5, 163, 106, 6, 43, 195, 232, 100, 41, 232, 138, 40, 139, 
X	194, 232, 133, 40, 137, 22, 212, 5, 195, 162, 110, 6, 138, 232, 50, 
X	201, 81, 232, 207, 43, 88, 117, 3, 233, 44, 1, 232, 158, 42, 232, 
X	29, 43, 255, 54, 210, 5, 161, 204, 5, 163, 210, 5, 255, 54, 202, 
X	5, 131, 46, 202, 5, 16, 232, 41, 250, 187, 4, 0, 51, 201, 232, 
X	226, 44, 117, 113, 83, 81, 255, 54, 202, 5, 131, 46, 202, 5, 4, 
X	232, 17, 250, 232, 76, 44, 19, 150, 185, 0, 0, 117, 2, 254, 205, 
X	81, 232, 223, 42, 89, 254, 193, 232, 180, 44, 116, 244, 81, 10, 237, 
X	117, 5, 232, 221, 44, 235, 16, 232, 157, 44, 116, 11, 161, 206, 5, 
X	45, 14, 0, 163, 78, 6, 235, 10, 136, 46, 108, 6, 232, 110, 4, 
X	232, 251, 2, 89, 93, 161, 78, 6, 137, 70, 254, 137, 78, 252, 161, 
X	86, 6, 10, 237, 116, 3, 184, 4, 0, 50, 237, 247, 225, 89, 91, 
X	3, 216, 254, 193, 232, 104, 44, 116, 146, 232, 203, 44, 232, 21, 42, 
X	128, 62, 110, 6, 6, 117, 57, 232, 141, 44, 83, 81, 198, 6, 108, 
X	6, 0, 232, 45, 4, 89, 91, 128, 62, 80, 6, 8, 115, 9, 128, 
X	62, 80, 6, 4, 232, 31, 250, 48, 93, 85, 161, 78, 6, 137, 70, 
X	254, 137, 94, 252, 138, 38, 235, 5, 254, 196, 176, 255, 137, 70, 250, 
X	3, 30, 86, 6, 232, 92, 44, 93, 88, 163, 210, 5, 161, 212, 5, 
X	128, 62, 111, 6, 0, 116, 3, 45, 25, 0, 137, 70, 248, 137, 94, 
X	246, 50, 237, 137, 78, 240, 161, 225, 5, 137, 70, 244, 199, 70, 242, 
X	0, 0, 128, 62, 111, 6, 0, 117, 75, 232, 116, 43, 151, 149, 117, 
X	15, 161, 218, 5, 137, 70, 244, 254, 78, 241, 232, 65, 39, 233, 23, 
X	44, 232, 94, 43, 159, 149, 117, 46, 233, 199, 1, 128, 126, 241, 0, 
X	232, 163, 249, 43, 128, 62, 111, 6, 0, 232, 162, 249, 76, 232, 74, 
X	44, 232, 246, 43, 198, 70, 241, 0, 139, 94, 244, 67, 161, 212, 5, 
X	43, 70, 248, 45, 3, 0, 232, 239, 39, 255, 54, 216, 5, 255, 54, 
X	210, 5, 161, 202, 5, 163, 210, 5, 85, 139, 70, 246, 128, 62, 110, 
X	6, 5, 116, 7, 139, 94, 254, 54, 43, 71, 254, 163, 216, 5, 254, 
X	6, 235, 5, 198, 70, 250, 0, 138, 78, 240, 139, 221, 131, 235
X};
X
Xpsub_ar roman_p = {
X	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
X	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
X	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
X	0, 1, 2, 28, 44, 150, 286, 417, 543, 574, 
X	640, 706, 822, 898, 929, 1005, 1036, 1127, 1263, 1349, 
X	1505, 1651, 1782, 1938, 2084, 2180, 2336, 2482, 2508, 2549, 
X	2665, 2791, 2907, 3013, 3214, 3355, 3526, 3642, 3773, 3934, 
X	4075, 4201, 4342, 4458, 4559, 4700, 4811, 4932, 5053, 5159, 
X	5300, 5451, 5612, 5803, 5914, 6025, 6136, 6227, 6368, 6499, 
X	6655, 6746, 6837, 6928, 7004, 7095, 7141, 7292, 7423, 7539, 
X	7645, 7791, 7907, 8043, 8164, 8230, 8326, 8447, 8503, 8604, 
X	8705, 8811, 8932, 9028, 9139, 9295, 9406, 9507, 9608, 9699, 
X	9840, 9981, 10117, 10233, 10249, 0, 0, -246, 2569, 4863, 
X	-246, 2578, 4863, -246, 2578, 4863, -246, 11785, 2559, -210, 
X	11785, 2559, -210, 11785, -29697, 2605, 11775, -246, 2605, 11775, 
X	-246, 2605, 7167, -228, 7195, 7167, -228, 7195, 7167, -228, 
X	2578, 2578, 4863, 4618, -246, 2578, 2578, 4863, 4618, -246, 
X	2578, 2578, 2559, -246, 2569, 2559, -246, 2569, 2559, -246, 
X	2578, 4863, -246, 2578, 4863, -246, 2578, 7167, -228, 7195, 
X	7167, -228, 7195, 7167, -228, 11659, -246, 2605, 11775, -246, 
X	2605, 11775, -246, 11785, 2559, -210, 11785, 2559, -210, 11785, 
X	2559, -246, 2569, 2559, -246, 2569, 2559, -246, 7186, 4863, 
X	-228, 7186, 4863, -228, 7186, 2559, -246, 2569, 2559, -246, 
X	2569, 2559, -246, 11785, 2559, -210, 11785, 2559, -210, 11785, 
X	-29697, 2569, 2587, 2559, 6922, -246, 2569, 2587, 2559, 6922, 
X	-246, 2569, 2587, 2559, 6922, -246, 2569, 2587, 2559, 6922, 
X	-246, 2569, 2587, 2559, 6922, -246, 2578, 2569, 4863, 2314, 
X	-246, 2578, 2569, 4863, 2314, -246, 2578, 2569, 7167, -246
X};
X
X#endif
END_OF_FILE
if test 7865 -ne `wc -c <'data.ad'`; then
    echo shar: \"'data.ad'\" unpacked with wrong size!
fi
# end of 'data.ad'
fi
if test -f 'egetopt.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'egetopt.c'\"
else
echo shar: Extracting \"'egetopt.c'\" \(12306 characters\)
sed "s/^X//" >'egetopt.c' <<'END_OF_FILE'
X/*
X * egetopt.c -- Extended 'getopt'.
X *
X * A while back, a public-domain version of getopt() was posted to the
X * net.  A bit later, a gentleman by the name of Keith Bostic made some
X * enhancements and reposted it.
X *
X * In recent weeks (i.e., early-to-mid 1988) there's been some
X * heated discussion in comp.lang.c about the merits and drawbacks
X * of getopt(), especially with regard to its handling of '?'.
X *
X * In light of this, I have taken Mr. Bostic's public-domain getopt()
X * and have made some changes that I hope will be considered to be
X * improvements.  I call this routine 'egetopt' ("Extended getopt").
X * The default behavior of this routine is the same as that of getopt(),
X * but it has some optional features that make it more useful.  These
X * options are controlled by the settings of some global variables.
X * By not setting any of these extra global variables, you will have
X * the same functionality as getopt(), which should satisfy those
X * purists who believe getopt() is perfect and can never be improved.
X * If, on the other hand, you are someone who isn't satisfied with the
X * status quo, egetopt() may very well give you the added capabilities
X * you want.
X *
X
Xegetopt() behaves like getopt() with the following added capabilities:
X
X--	The '?' which gets returned when there is an unrecognized option
X	is now stored in a global integer called 'optbad', and the caller
X	can set this value to anything.  The initial value in 'optbad' is
X    	'?', which means that the default behavior is just like that of
X    	getopt().  For example, If you want egetopt() to return '~'
X    	instead of '?' when it sees an invalid option, put the following
X    	lines in your code before egetopt() gets called:
X
X		extern int optbad;
X		optbad = (int)'~';
X
X--	Options can begin with characters other than just '-'.  There
X	is now a global character pointer called 'optstart'.  It points
X	to a string which consists of a list of characters which can
X	be used to begin options.  The initial string that 'optstart'
X	points to is "-", so the default behavior is like that of
X    	getopt().  For example, if you want to allow both '+' and '-'
X    	as option delimiters, put the following lines in your code
X    	before egetopt() gets called:
X
X		extern char *optstart;
X		optstart = "-+";
X
X--	Now that there's a choice of the characters that can precede options
X	it's desirable to let the caller know what character begins a
X	given option.  In egetopt(), the global integer 'optchar' will
X	now contain the character that begins a given option, or 0 if
X	there was an error.  Just put the following line in your code
X	and you can check the value of 'optchar' after each call to
X	egetopt():
X
X		extern int optchar;
X
X--	The old getopt() writes error messages to file descriptor 2
X	(or to stderr, depending on your implementation).  In egetopt(),
X	you can change this file descriptor to be anything you want.
X	The global integer 'opterrfd' contains the file descriptor
X	to use for writing error messages.  As you might have guessed,
X	this variable is initialized to 2.  As an example, if you want
X	your egetopt() errors to go to the file "egetopt.errs", do
X    	something similar to the following before calling egetopt():
X
X		extern int opterrfd;
X
X		FILE *eout = fopen("egetopt.errs", "w");
X
X		if (eout == (FILE)NULL) {
X			/* error condition/
X			...
X			exit(1);
X		}
X
X		opterrfd = fileno(eout);
X
X--	Some implementations of getopt() allow you to set the global
X	integer 'opterr' to control whether error output is printed:
X	it is initialized to 1, which enables error output (as does
X	any non-zero value); setting it to 0 disables error output.
X	In egetopt(), 'opterr' is treated the same way.
X
X--	The old getopt() forces you to use ':' in the string of option
X	letters to show that a given option takes an argument.  There is
X	now a global integer called 'optneed' which contains this value,
X	so you can change it to something else if you want.  As you might
X    	have suspected, 'optneed' is initialized to ':'.
X
X	In addition, something that I always found annoying about the old
X	getopt() is its inability to handle non-mandatory option arguments.
X	For example, if an option called 'd' was specified as taking
X	an argument to the program 'foo', you'd get the following
X	results when invoking 'foo' in different ways:
X
X	1)	foo -dABC -x ...
X
X			getopt() return:	'd'
X			optarg:			"ABC"
X
X	2)	foo -dABC -x ...
X
X			getopt() return:	'd'
X			optarg:			"ABC"
X
X	3)	foo -d -x ...
X
X		A)	getopt() return:	'd'
X			optarg:			"-x"
X
X	In the case of number 3, sometimes one would prefer to get ...
X
X		B)	getopt() return:	'd'
X			optarg:			NULL
X
X	This would allow "-x" to be handled as another option in the next
X	call.  In the old getopt(), you can get the 3B behavior by testing
X	the first character of 'optarg' and decrementing 'optind' if this
X	character is '-'.  However, since I am enhancing the routine
X    	anyway, I decided to build in the ability to have either the 3A
X    	or the 3B behavior.
X
X	Since this behavior isn't always desired, I have added another
X	global integer called 'optmaybe' which optionally allows you to
X	control whether an option with an argument will get treated as number
X	3A or as number 3B above.  It is used similarly to 'optneed'.  It is
X	initialized to 0, meaning that behavior 3B is impossible in the
X	default case.  The following example shows how 'optneed' and
X	'optmaybe' can be used:
X
X    	    	extern int optneed;
X       	    	extern int optmaybe;
X
X    	    	optneed = (int)'!';	/* use '!' instead of ':'/
X		optmaybe = (int)'%';	/* use '%' for optional arguments/
X
X		...
X
X		while ((c = egetopt(argc, argv, "abc!d%x")) != EOF) ...
X
X	In this example, options 'a', 'b', and 'x' take no arguments,
X	option 'c' takes a mandatory argument, and option 'd' takes
X	a non-mandatory argument.  If this is contained in program 'foo',
X    	you'll get the following behavior when you run it:
X
X		foo -a -cABC -dXYZ -d -x -c -b ...
X
X			egetopt() return:	'a'
X			optarg:			NULL
X
X			egetopt() return:	'c'
X			optarg:			"ABC"
X
X			egetopt() return:	'd'
X			optarg:			"XYZ"
X
X	>>>>>>>>>>	egetopt() return:	'd'
X	>>>>>>>>>>	optarg:			NULL
X	>> NOTE >>
X	>>>>>>>>>>	egetopt() return:	'x'
X	>>>>>>>>>>	optarg:			NULL
X
X			egetopt() return:	'c'
X			optarg:			"-b"
X
X			...
X
X	Remember that 'optneed' is initialized to ':' and 'optmaybe'
X	is initialized to 0.  This causes behavior identical to that
X	of getopt() unless you specifically override it.
X
XSince the default behavior of egetopt() is the same as that of getopt(),
Xthere is no reason why you can't rename this routine to getopt() and
Xuse it in place of the original.  I gave it a new name so as not to
Xoffend those of you who believe that getopt() is perfect and should
Xnever have any new features added to it.
X
X
X 
X * The code was originally posted to the net as getopt.c by ...
X *
X *	Keith Bostic
X *	ARPA: keith@seismo 
X *	UUCP: seismo!keith
X *
X * Current version: added enhancements and comments, reformatted code.
X *
X *	Lloyd Zusman
X *	Master Byte Software
X *	Los Gatos, California
X *	Internet:	ljz@fx.com
X *	UUCP:		...!ames!fxgrp!ljz
X *
X *    	May, 1988
X */
X
X/*
X * If you want, include stdio.h or something where EOF and NULL are defined.
X * However, egetopt() is written so as not to need stdio.h, which should
X * make it significantly smaller on some systems.
X */
X
X#ifndef EOF
X# define EOF		(-1)
X#endif /* ! EOF */
X
X#ifndef NULL
X# define NULL		(char *)0
X#endif /* ! NULL */
X
X/*
X * None of these constants are referenced in the executable portion of
X * the code ... their sole purpose is to initialize global variables.
X */
X#define BADCH		(int)'?'
X#define NEEDSEP		(int)':'
X#define MAYBESEP	(int)'\0'
X#define ERRFD		2
X#define EMSG		""
X#define START		"-"
X
X/*
X * Here are all the pertinent global variables.
X */
Xint opterr = 1;		/* if true, output error message */
Xint optind = 1;		/* index into parent argv vector */
Xint optopt;		/* character checked for validity */
Xint optbad = BADCH;	/* character returned on error */
Xint optchar = 0;	/* character that begins returned option */
Xint optneed = NEEDSEP;	/* flag for mandatory argument */
Xint optmaybe = MAYBESEP;/* flag for optional argument */
Xint opterrfd = ERRFD;	/* file descriptor for error text */
Xchar *optarg;		/* argument associated with option */
Xchar *optstart = START;	/* list of characters that start options */
X
X
X/*
X * Macros.
X */
X
X/*
X * Conditionally print out an error message and return (depends on the
X * setting of 'opterr' and 'opterrfd').  Note that this version of
X * TELL() doesn't require the existence of stdio.h.
X */
X#define TELL(S)	{ \
X	if (opterr && opterrfd >= 0) { \
X		char option = optopt; \
X		write(opterrfd, *nargv, strlen(*nargv)); \
X		write(opterrfd, (S), strlen(S)); \
X		write(opterrfd, &option, 1); \
X		write(opterrfd, "\n", 1); \
X	} \
X	return (optbad); \
X}
X
X/*
X * This works similarly to index() and strchr().  I include it so that you
X * don't need to be concerned as to which one your system has.
X */
Xstatic char *
X_sindex(string, ch)
Xchar *string;
Xint ch;
X{
X	if (string != NULL) {
X		for (; *string != '\0'; ++string) {
X			if (*string == (char)ch) {
X				return (string);
X			}
X		}
X	}
X
X	return (NULL);
X}
X
X/*
X * Here it is:
X */
Xint
Xegetopt(nargc, nargv, ostr)
Xint nargc;
Xchar **nargv;
Xchar *ostr;
X{
X	static char *place = EMSG;	/* option letter processing */
X	register char *oli;		/* option letter list index */
X	register char *osi = NULL;	/* option start list index */
X
X	if (nargv == (char **)NULL) {
X		return (EOF);
X	}
X
X	if (nargc <= optind || nargv[optind] == NULL) {
X		return (EOF);
X	}
X
X	if (place == NULL) {
X		place = EMSG;
X	}
X
X	/*
X	 * Update scanning pointer.
X	 */
X	if (*place == '\0') {
X		place = nargv[optind];
X		if (place == NULL) {
X			return (EOF);
X		}
X		osi = _sindex(optstart, *place);
X		if (osi != NULL) {
X			optchar = (int)*osi;
X		}
X		if (optind >= nargc || osi == NULL || *++place == '\0') {
X		    	return (EOF);
X		}
X
X		/*
X		 * Two adjacent, identical flag characters were found.
X		 * This takes care of "--", for example.
X		 */
X		if (*place == place[-1]) {
X			++optind;
X			return (EOF);
X		}
X	}
X
X	/*
X	 * If the option is a separator or the option isn't in the list,
X	 * we've got an error.
X	 */
X	optopt = (int)*place++;
X	oli = _sindex(ostr, optopt);
X	if (optopt == optneed || optopt == optmaybe || oli == NULL) {
X		/*
X		 * If we're at the end of the current argument, bump the
X		 * argument index.
X		 */
X		if (*place == '\0') {
X			++optind;
X		}
X		TELL(": illegal option -- ");	/* byebye */
X	}
X
X	/*
X	 * If there is no argument indicator, then we don't even try to
X	 * return an argument.
X	 */
X	++oli;
X	if (*oli == '\0' || (*oli != optneed && *oli != optmaybe)) {
X		/*
X		 * If we're at the end of the current argument, bump the
X		 * argument index.
X		 */
X		if (*place == '\0') {
X			++optind;
X		}
X		optarg = NULL;
X	}
X	/*
X	 * If we're here, there's an argument indicator.  It's handled
X	 * differently depending on whether it's a mandatory or an
X	 * optional argument.
X	 */
X	else {
X		/*
X		 * If there's no white space, use the rest of the
X		 * string as the argument.  In this case, it doesn't
X		 * matter if the argument is mandatory or optional.
X		 */
X		if (*place != '\0') {
X			optarg = place;
X		}
X		/*
X		 * If we're here, there's whitespace after the option.
X		 *
X		 * Is it a mandatory argument?  If so, return the
X		 * next command-line argument if there is one.
X		 */
X		else if (*oli == optneed) {
X			/*
X			 * If we're at the end of the argument list, there
X			 * isn't an argument and hence we have an error.
X			 * Otherwise, make 'optarg' point to the argument.
X			 */
X			if (nargc <= ++optind) {
X				place = EMSG;
X				TELL(": option requires an argument -- ");
X			}
X			else {
X				optarg = nargv[optind];
X			}
X		}
X		/*
X		 * If we're here it must have been an optional argument.
X		 */
X		else {
X			if (nargc <= ++optind) {
X				place = EMSG;
X				optarg = NULL;
X			}
X			else {
X				optarg = nargv[optind];
X				if (optarg == NULL) {
X					place = EMSG;
X				}
X				/*
X				 * If the next item begins with a flag
X				 * character, we treat it like a new
X				 * argument.  This is accomplished by
X				 * decrementing 'optind' and returning
X				 * a null argument.
X				 */
X				else if (_sindex(optstart, *optarg) != NULL) {
X					--optind;
X					optarg = NULL;
X				}
X			}
X		}
X		place = EMSG;
X		++optind;
X	}
X
X	/*
X	 * Return option letter.
X	 */
X	return (optopt);
X}
END_OF_FILE
if test 12306 -ne `wc -c <'egetopt.c'`; then
    echo shar: \"'egetopt.c'\" unpacked with wrong size!
fi
# end of 'egetopt.c'
fi
echo shar: End of archive 1 \(of 4\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

-- 
Jonathan Bayer			      Beware: The light at the end of the
Intelligent Software Products, Inc.	      tunnel may be an oncoming dragon
500 Oakwood Ave.				...uunet!ispi!root
Roselle Park, NJ   07204    (201) 245-5922    jbayer@ispi.UUCP