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