label: format labels for photocopy master sheets
Gary Perlman
perlman at wanginst.UUCP
Fri Nov 8 09:41:22 AEST 1985
Enclosed is a label making program. It is really useful if
you want to do mass mailings, or for making sheets of all
the same label, like for products. There is a simpe program
included to zipsort labels.
It is designed to adapt to any format label copying sheet.
I have found it best to get some photocopier labels sheets
from an office supply store and then tailer a shell script
to fit that label. Two local shell scripts, big_label and
small_label are examples of this. The shell scripts make it
pretty easy for secretarial staff to use the program,
otherwise, you have to explain UNIX options.
Here is a quick example. The defaults print 3 labels across
a sheet, each with six lines, the first of which is blank.
Everything is programmable. The options in the exampple
change the label width and the number of copies of each
label requested.
label -w 25 -n 2 << 'EOF'
John Doe:123 Maple Lane:Anytown, USA
Jane Doe:1600 Penn. Ave.:Washington, DC
EOF
------------output
John Doe John Doe Jane Doe
123 Maple Lane 123 Maple Lane 1600 Penn. Ave.
Anytown, USA Anytown, USA Washington, DC
Jane Doe
1600 Penn. Ave.
Washington, DC
------------end of output
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# label.1
# intro
# zipsort.1
# makefile
# label.c
# number.c
# filter.c
# big_label
# small_label
# zipsort.c
# This archive created: Thu Nov 7 18:38:24 1985
# By: Gary Perlman (Wang Institute, Tyngsboro, MA 01879 USA)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'label.1'" '(2121 characters)'
if test -f 'label.1'
then
echo shar: "will not over-write existing file 'label.1'"
else
sed 's/^ X//' << \SHAR_EOF > 'label.1'
X.TH LABEL "1WI" "November 1985" "Wang Institute" "UNIX User's Manual"
X.SH NAME
Xlabel \- print label sheet
X.SH USAGE
X.I label
X[-cU] [-d\ delim] [-h\ height] [-i\ indent] [-l\ count] [-n\ repeat]
X.ti +.5i
X[-s\ skip] [-w\ width] [-] [files]
X.SH OPTIONS
X.I label
Xoptions adjust to different label page formats by
Xcontrolling the number of labels across a page,
Xthe label height and width, and so on..
X.de OP\" option-letter [optional value]
X.TP
X.B -\\$1 \\$2
X..
X.OP c
XCenter text on each line in the label.
XThis option resets the label indent to 0.
X.OP d delim
XThe label line field delimiter (default: `:' the colon) tells
X.I label
Xhow to separate fields in a line.
XThis character should not appear in the fields you want to print.
XSeveral field delimiters in a row (blank fields) are skipped.
XIf you really want a blank line inside a label, use a space.
X.OP h height
XThe height of a label (default: 6 lines).
X.OP i indent
XThe number of spaces to indent before each label (default: 2).
X.OP l labels
XThe number of labels to fit across a page (default: 3).
X.OP n number
XThe number of times to repeat each label (default: 1).
X.OP s skip
XThe number of lines to skip at the top of each label (default: 1).
X.OP U
XPrint a usage summary and exit.
X.OP w width
XThe label width in spaces (default 33).
X.SH DESCRIPTION
X.PP
X.I label
Xprints a series of labels in a matrix on a page
Xthat is then suitable to use as a copy master for a page of stick on labels.
XIf the labels are read in order: 1 2 3 4 5 6,
Xand printed three across a page,
Xthen the output is arranged like:
X.nf
X 1 2 3
X 4 5 6
X.fi
X.SS Input
X.I label
Xreads non-blank lines that contain a series of delimited fields.
XThe delimiter is a single character that separates the fields.
XEach field is used as one line in a label.
XExample labels:
X.ce 2
XGary Perlman:Wang Institute:Tyng Road:Tyngsboro, MA 01879
XCopyright (c) 1985:Wang Institute:All Rights Reserved
X.SS Output
X.I label
Xreads label lines until it has enough to print a row of labels.
X.SH EXAMPLE
X.nf
XPrint six-high labels, four across, for 12 pitch print (100 wide):
X label -h 6 -l 4 -w 25
X.fi
X.SH AUTHOR
XGary Perlman
SHAR_EOF
if test 2121 -ne "`wc -c < 'label.1'`"
then
echo shar: "error transmitting 'label.1'" '(should have been 2121 characters)'
fi
fi
echo shar: "extracting 'intro'" '(7110 characters)'
if test -f 'intro'
then
echo shar: "will not over-write existing file 'intro'"
else
sed 's/^ X//' << \SHAR_EOF > 'intro'
X Making Labels
X Gary Perlman
X
XI am pleased to announce public release of my new label
Xprogram. This program takes label-lines and lays them out
Xfor transfer onto label master sheets. Although hard to
Xbelieve, there is a lot of technical information behind
Xprinting labels, and this document will help you.
X
X Definitions
X
XLabel Master Sheets: These are 8.5 X 11 inch sheets with
Xself-adhesive labels. The sheets are designed for jam-free
Xphotocopy transfer from printed sheets. There are many
Xsizes of label master sheet layouts. Here at the Wang
XInstitute, we have two:
X
X Across Sheet Top-to-Bottom
X #labels #characters #labels #lines
X small 3 33 11 6
X big 2 50 5 12
X
XThe number of available characters assumes 12-pitch
Xprinting, or 100 characters per line. This is how our
XDiablo printer is set up. For small labels, there is a
Xcharacter not accounted for (3 labels times 33 characters is
X99, not 100 characters). This missing character is cleaned
Xup in a shell script, small_label, that sets all the options
Xneeded for small-label master sheets. For big labels, there
Xare three lines at the top of the page, and three lines at
Xthe bottom (5 labels times 12 lines is 60, not 66 lines).
XThese extra lines are cleaned up in a shell script,
Xbig_label, that sets all the options needed for big-label
Xmaster sheets.
X
XLabel Layout: A label master sheet is a matrix of labels,
Xwhile a set of label description lines comes in
Xline-by-line. The goal of the label program is to arrange
Xthe labels so that they fit on the labels on the master
Xsheet. For labels numbered 1 to 9 to fit on a small-label
Xmaster sheet, that means the labels should be arranged like
Xthis:
X 1 2 3
X 4 5 6
X 7 8 9
X
XLabel-Lines: The input to the label program is a series of
Xlines, each with one label per line. But because each label
Xis several lines, a special character, the field delimiter,
Xmust be used to separate different lines within a label,
Xcalled fields. By default, this character is the colon (:),
Xbut it can be changed to another character if a colon must
Xappear in a label line. An example label-line is:
X
X G. Perlman:Wang Institute:Tyng Road:Tyngsboro, MA 01879
X
XThere are four fields in this label. Two copies of this
Xlabel, spanning this page width, would look like this:
X
X G. Perlman G. Perlman
X Wang Institute Wang Institute
X Tyng Road Tyng Road
X Tyngsboro, MA 01879 Tyngsboro, MA 01879
X
XNote that there is a blank line at the top of the labels,
Xand that each label is indented two spaces.
X
X Aesthetics
X
XAlthough small labels have 6 lines and 33 characters, and
Xbig labels have 12 lines and 50 characters, not all the
Xlabel is usable. It is common practice to leave the first
X(few) and last (few) lines of a label clear, and to indent
Xthe text on labels at least one or two spaces. This looks
Xbetter, and it makes the alignment of text on the labels
Xless critical. The big_label and small_label shell scripts
Xassume that upper and left margins are wanted on all labels.
X
X Pragmatics
X
XTo make some labels, here is what you do, step by step.
X
XFirst, you must type in your labels, one per line, in the
Xformat described above. Let's assume your labels are in a
XUNIX file called "mylabels".
X
XSecond, you must decide what sort of labels you want, big or
Xsmall. For most address labels, the small labels are too
Xsmall, so the big ones should be used. For labels like name
Xtags, the small labels are okay.
X
XThird, you put your labels through the label program, or,
Xmore likely, through one of the convenient shell scripts:
Xsmall_label or big_label. Let's assume you will use the
Xbig-label master sheets. The call to big_label (that is an
Xunderscore between big and label) would look like this:
X big_label mylabels
X
XBut that would just print the labels out on your screen,
Xwhich is not very useful. So you can save the output from
Xthe label program in a file, which we'll assume is called
X"mysheet":
X big_label mylabels > mysheet
X
XFourth, print the formatted label sheet on a printer, like
Xthe Diablo printer. The printer should be set up so that
Xprinting will start in the extreme upper left hand corner of
Xthe page. The print command would look like this:
X lpr -Pdiablo mysheet
X
XNote that the steps to make the labels and print them can be
Xcombined using UNIX pipes. This also avoids creating the
Xfile "mysheet" which serves no useful purpose. The combined
Xcommand would be:
X big_label mylabels | lpr -Pdiablo
X
XFifth, take the printed label sheet and transfer it onto a
Xsheet of self-adhesive labels. These can be hand fed in a
Xphotocopy machine, or stacked into the paper feed bin. The
Xsheets are specially made to not jam up the copy machine.
XBecause the Diablo printer often has alignment problems, the
Xprinted sheet may have to be adjusted a bit to match up with
Xthe self-adhesive label master sheet.
X
X Frills
X
XThe label program has several options, many of which are
Xused in the shell scripts big_label and small_label. In
Xthis section, I will discuss the options you may are most
Xlikely to use. All these options can be used with the shell
Xscripts, or with the label program directly. First, there
Xis a -U option, that will give you a usage summary of the
Xprogram (with the current options) so that:
X small_label -U
Xwill print:
X label: format label sheet
X -c center fields on each label line
X -d C field delimiter character (:)
X -h N height in lines of labels (6 lines)
X -i N indent before each label (2 spaces)
X -l N number of label across page (3)
X -n N repeat each label N times (1 times)
X -s N skip lines at label top (1 lines)
X -U print this usage message
X -w N label width (33 spaces)
X
XThe center option (-c) will center all the fields on each
Xline of the printed labels. This is pretty on labels other
Xthan address labels. The -n option tells label the number
Xof times to print each label. By default, label prints one
Xcopy, but sometimes more than one is wanted, such as when
Xyou want to fill a sheet with one label to have a stock.
XHere is an example using the -c and the -n options:
X
X small_label -c -n 33 copyright
X
Xwhere the file "copyright" contains one label:
X
X Copyright (c) 1985:Wang Institute:All Rights Reserved
X
XA two-column two copy version of this label to fit this page
Xwould look like this:
X label -l 2 -w 30 -c -n 2
X
X Copyright (c) 1985 Copyright (c) 1985
X Wang Institute Wang Institute
X All Rights Reserved All Rights Reserved
SHAR_EOF
if test 7110 -ne "`wc -c < 'intro'`"
then
echo shar: "error transmitting 'intro'" '(should have been 7110 characters)'
fi
fi
echo shar: "extracting 'zipsort.1'" '(538 characters)'
if test -f 'zipsort.1'
then
echo shar: "will not over-write existing file 'zipsort.1'"
else
sed 's/^ X//' << \SHAR_EOF > 'zipsort.1'
X.TH ZIPSORT "1WI" "November 1985" "Wang Institute" "UNIX User's Manual"
X.SH NAME
Xzipsort \- sort lines by zipcode
X.SH USAGE
X.I zipsort
X[-] [files]
X.SH DESCRIPTION
X.I zipsort
Xreads a series of lines from the named files or the standard input
Xand sorts them by zipcode (a five long series of digits).
XIf there are more than one number on a line that looks like
Xa zipcode, the last is used.
X.SH "SEE ALSO"
Xlabel(1W)
X.SH AUTHOR(S)
XGary Perlman
X.SH WARNING
X.I zipsort
Xassumes that the
X.I sort
Xand
X.I sed
Xutilities are available on the system.
SHAR_EOF
if test 538 -ne "`wc -c < 'zipsort.1'`"
then
echo shar: "error transmitting 'zipsort.1'" '(should have been 538 characters)'
fi
fi
echo shar: "extracting 'makefile'" '(768 characters)'
if test -f 'makefile'
then
echo shar: "will not over-write existing file 'makefile'"
else
sed 's/^ X//' << \SHAR_EOF > 'makefile'
XMAIN=label
XHDRS=
XSRCS=number.c filter.c
XOBJS=number.o filter.o
XDOCS=label.1 intro zipsort.1
XLIBS=
XDESTDIR=.
XCFLAGS=-O
XTEXT=$(HDRS) $(MAIN).c $(SRCS)
X
XLINT =/usr/bin/lint -hp
XPR =@cpr
XSPELL =sp
XSHAR =shar -a
XRCS =ci -l
XCC =/bin/cc
X
X$(MAIN): $(MAIN).o $(OBJS)
X $(CC) $(CFLAGS) -o $(MAIN) $(MAIN).o $(OBJS)
X
Xzipsort: zipsort.o
X $(CC) *(CFLAGS) -o zipsort zipsort.o
X
Xinstall: $(MAIN) zipsort
X cp -i $(MAIN) zipsort $(DESTDIR)/$(MAIN)
X
Xprint:
X $(PR) $(MAIN).c
X
Xlint:
X $(LINT) $(TEXT)
X
Xspell:
X seec -cqe $(TEXT) | $(SPELL)
X
Xarchive:
X $(SHAR) $(DOCS) [Mm]akefile $(TEXT) *_label zipsort.c > archive
X
Xclean:
X rm -f *.o core a.out mon.out gmon.out scmon.out
X
X$(MAIN).1: $(MAIN).c
X @seec -t MANUAL $(MAIN).c > $(MAIN).1
X
X.PRECIOUS: $(TEXT) $(DOCS) zipsort.c zipsort.1
SHAR_EOF
if test 768 -ne "`wc -c < 'makefile'`"
then
echo shar: "error transmitting 'makefile'" '(should have been 768 characters)'
fi
fi
echo shar: "extracting 'label.c'" '(9423 characters)'
if test -f 'label.c'
then
echo shar: "will not over-write existing file 'label.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'label.c'
X/*MANUAL.TH LABEL "1WI" "November 1985" "Wang Institute" "UNIX User's Manual"
X*/
X
X/*MANUAL.SH NAME
Xlabel \- print label sheet
X*/
X
X/*MANUAL.SH USAGE
X.I label
X[-cU] [-d\ delim] [-h\ height] [-i\ indent] [-l\ count] [-n\ repeat]
X.ti +.5i
X[-s\ skip] [-w\ width] [-] [files]
X*/
X
X#include <stdio.h>
X#include <ctype.h>
X
X#define MAXFIELDS 30 /* max number of labels across */
X
Xtypedef int Status; /* return/exit status of functions */
X#define SUCCESS ((Status) 0)
X#define FAILURE ((Status) 1)
Xtypedef int Boole; /* no Boolean type in C */
X#define TRUE ((Boole) 1)
X#define FALSE ((Boole) 0)
X#define EOS '\0'
X
Xchar *Argv0; /* program name */
Xchar *File; /* current file name */
Xint Labelcount; /* current label number in File */
Xint Linecount; /* current line number in File */
X
X/*MANUAL.SH OPTIONS
X.I label
Xoptions adjust to different label page formats by
Xcontrolling the number of labels across a page,
Xthe label height and width, and so on..
X.de OP\" option-letter [optional value]
X.TP
X.B -\\$1 \\$2
X..
X*/
X
XBoole Center = FALSE; /*MANUAL.OP c
XCenter text on each line in the label.
XThis option resets the label indent to 0.
X*/
X
Xchar Delim = ':'; /*MANUAL.OP d delim
XThe label line field delimiter (default: `:' the colon) tells
X.I label
Xhow to separate fields in a line.
XThis character should not appear in the fields you want to print.
XSeveral field delimiters in a row (blank fields) are skipped.
XIf you really want a blank line inside a label, use a space.
X*/
X
Xint Realheight; /* Labheight - Labskip */
Xint Labheight = 6; /*MANUAL.OP h height
XThe height of a label (default: 6 lines).
X*/
X
Xint Labindent = 2; /*MANUAL.OP i indent
XThe number of spaces to indent before each label (default: 2).
X*/
X
Xint Nlabels = 3; /*MANUAL.OP l labels
XThe number of labels to fit across a page (default: 3).
X*/
X
Xint Repeat = 1; /*MANUAL.OP n number
XThe number of times to repeat each label (default: 1).
X*/
X
Xint Labskip = 1; /*MANUAL.OP s skip
XThe number of lines to skip at the top of each label (default: 1).
X*/
X
X/*MANUAL.OP U
XPrint a usage summary and exit.
X*/
X
Xint Realwidth; /* usable width of label (Labwidth - Labindent) */
Xint Labwidth = 33; /*MANUAL.OP w width
XThe label width in spaces (default 33).
X*/
X
X/*FUNCTION printusage: on-line help */
Xvoid
Xprintusage ()
X {
X fprintf (stderr, "%s: format label sheet\n", Argv0);
X fprintf (stderr, "-c center fields on each label line\n");
X fprintf (stderr, "-d C field delimiter character (%c)\n", Delim);
X fprintf (stderr, "-h N height in lines of labels (%d lines)\n", Labheight);
X fprintf (stderr, "-i N indent before each label (%d spaces)\n", Labindent);
X fprintf (stderr, "-l N number of label across page (%d)\n", Nlabels);
X fprintf (stderr, "-n N repeat each label N times (%d times)\n", Repeat);
X fprintf (stderr, "-s N skip lines at label top (%d lines)\n", Labskip);
X fprintf (stderr, "-U print this usage message\n");
X fprintf (stderr, "-v verbose information printed\n");
X fprintf (stderr, "-w N label width (%d spaces)\n", Labwidth);
X }
X
X/*FUNCTION getint: set integer, checking type and range */
XStatus
Xgetint (flag, string, varptr, min, max)
Xint flag;
Xchar *string;
Xint *varptr;
Xint min;
Xint max;
X {
X int retval = FAILURE;
X if (number (string) == 1) /* an integer */
X {
X int value = atoi (string);
X if (value >= min && value <= max)
X {
X *varptr = value;
X retval = SUCCESS;
X }
X else
X {
X fprintf (stderr, "\007%s: -%c value (%s) must be between %d and %d\n",
X Argv0, flag, string, min, max);
X }
X }
X else
X fprintf (stderr, "\007%s: -%c value (%s) must be an integer\n",
X Argv0, flag, string);
X return (retval);
X }
X
Xvoid
Xnputchar (c, n)
X {
X while (n-- > 0)
X putchar (c);
X }
X
X/*FUNCTION initial: returns local version of optind, index to first operand */
Xint
Xinitial (argc, argv) char **argv;
X {
X extern char *optarg; /* option value accessed through this by getopt */
X extern int optind; /* will be index to first operand */
X int opterr = 0; /* count of number of errors */
X int flag; /* option flag characters read in here */
X char *optstring = /* getopt string */
X "cd:h:i:l:n:s:Uw:";
X char *usage = /* variable part of usage summary */
X "[-cU] [-d delim] [-h height] [-i indent] [-l count] [-n repeat]\n\t[-s skip] [-w width] [-] [files]";
X
X Argv0 = argv[0];
X
X while ((flag = getopt (argc, argv, optstring)) != EOF)
X switch (flag) /* put option cases here */
X {
X default:
X opterr++;
X break;
X case 'U':
X printusage ();
X exit (0);
X case 'c':
X Center = TRUE;
X Labindent = 0;
X break;
X case 'd':
X Delim = *optarg;
X break;
X case 'h':
X if (getint (flag, optarg, &Labheight, 0, 100) == FAILURE)
X opterr++;
X break;
X case 'i':
X if (getint (flag, optarg, &Labindent, 0, 100) == FAILURE)
X opterr++;
X break;
X case 'l':
X if (getint (flag, optarg, &Nlabels, 1, MAXFIELDS) == FAILURE)
X opterr++;
X break;
X case 'n':
X if (getint (flag, optarg, &Repeat, 1, 100) == FAILURE)
X opterr++;
X break;
X case 's':
X if (getint (flag, optarg, &Labskip, 0, 100) == FAILURE)
X opterr++;
X break;
X case 'w':
X if (getint (flag, optarg, &Labwidth, 10, 150) == FAILURE)
X opterr++;
X break;
X }
X
X if (opterr)
X {
X fprintf (stderr, "\007Usage: %s %s\n", argv[0], usage);
X exit (1);
X }
X
X Realwidth = Labwidth - Labindent;
X Realheight = Labheight - Labskip;
X
X return (optind);
X }
X
X/*FUNCTION main: loop through files in classic UNIX filter style */
Xvoid
Xmain (argc, argv)
Xint argc; /* argument count */
Xchar **argv; /* argument vector */
X {
X Status label (); /* label (file, ioptr) will filter files */
X Status status; /* return status of filter () */
X int firstfile; /* first file name index returned by initial */
X firstfile = initial (argc, argv);
X status = filter (argc, argv, firstfile, label);
X exit (status);
X }
X
X/*FUNCTION geline: get non-blank input line and duplicate as needed */
Xchar *
Xgetline (line, size, ioptr)
Xchar *line;
XFILE *ioptr;
X {
X static char buf[BUFSIZ];
X static int nrepeat = 0;
X char *ptr = buf;
X
X if (nrepeat == 0)
X {
X do
X {
X if (fgets (ptr = buf, size, ioptr) == NULL)
X return (NULL);
X Linecount++;
X while (isspace (*ptr))
X ptr++;
X } while (*ptr == '\0');
X Labelcount++;
X checklabel (buf);
X }
X strncpy (line, buf, size);
X if (++nrepeat == Repeat)
X nrepeat = 0;
X return (line);
X }
X
X/*FUNCTION fieldprint: print a field in a label */
Xchar *
Xfieldprint (lptr)
Xchar *lptr;
X {
X char *eptr = lptr;
X int len; /* field length */
X int pad; /* pad needed for field */
X
X while (*eptr && *eptr != Delim && *eptr != '\n') eptr++;
X while (*eptr == Delim)
X *eptr++ = EOS;
X if (*eptr == '\n')
X *eptr = EOS;
X
X nputchar (' ', Labindent);
X len = strlen (lptr);
X if (len > Realwidth)
X {
X lptr[Realwidth] = '\0';
X pad = 0;
X }
X else
X pad = Realwidth - len;
X
X if (Center)
X {
X nputchar (' ', pad / 2);
X pad -= pad / 2;
X }
X printf (lptr);
X nputchar (' ', pad);
X
X return (eptr);
X }
X
X/*MANUAL.SH DESCRIPTION
X.PP
X.I label
Xprints a series of labels in a matrix on a page
Xthat is then suitable to use as a copy master for a page of stick on labels.
XIf the labels are read in order: 1 2 3 4 5 6,
Xand printed three across a page,
Xthen the output is arranged like:
X.nf
X 1 2 3
X 4 5 6
X.fi
X.SS Input
X.I label
Xreads non-blank lines that contain a series of delimited fields.
XThe delimiter is a single character that separates the fields.
XEach field is used as one line in a label.
XExample labels:
X.ce 2
XGary Perlman:Wang Institute:Tyng Road:Tyngsboro, MA 01879
XCopyright (c) 1985:Wang Institute:All Rights Reserved
X.SS Output
X.I label
Xreads label lines until it has enough to print a row of labels.
X*/
X
X/*MANUAL.SH EXAMPLE
X.nf
XPrint six-high labels, four across, for 12 pitch print (100 wide):
X label -h 6 -l 4 -w 25
X.fi
X*/
X
X/*MANUAL.SH AUTHOR
XGary Perlman
X*/
X
X/*FUNCTION checklabel: print warnings about problems with label */
Xchecklabel (line)
Xchar *line;
X {
X char *ptr;
X int nfields = 0; /* number of fields in label */
X Boole truncate = FALSE; /* are fields truncated? */
X
X for (;;)
X {
X for (ptr = line; *ptr && *ptr != '\n' && *ptr != Delim; ptr++);
X if (ptr - line > Realwidth)
X truncate = TRUE;
X while (*ptr == Delim)
X ptr++;
X nfields++;
X if (*ptr == EOS || *ptr == '\n')
X break;
X line = ptr;
X }
X
X if (nfields > Realheight)
X fprintf (stderr, "\007%s: Field ignored in label %d on line %d in %s\n",
X Argv0, Labelcount, Linecount, File);
X
X if (truncate == TRUE)
X fprintf (stderr, "\007%s: Field truncated in label %d on line %d in %s\n",
X Argv0, Labelcount, Linecount, File);
X }
X
X/*FUNCTION label: main routine */
XStatus
Xlabel (file, ioptr)
Xchar *file;
XFILE *ioptr;
X {
X char labbuf[MAXFIELDS][BUFSIZ], *lptr[MAXFIELDS];
X int line, col;
X
X File = file;
X Labelcount = 0;
X
X for (;;)
X {
X for (col = 0; col < Nlabels; col++)
X {
X if (getline (labbuf[col], BUFSIZ, ioptr) == NULL)
X if (col == 0) /* no labels read in, just quit */
X return (SUCCESS);
X else /* at least one label read in, use blanks to pad */
X labbuf[col][0] = EOS;
X lptr[col] = labbuf[col];
X }
X nputchar ('\n', Labskip);
X for (line = 0; line < Labheight-Labskip; line++)
X {
X for (col = 0; col < Nlabels; col++)
X lptr[col] = fieldprint (lptr[col]);
X putchar ('\n');
X }
X }
X }
SHAR_EOF
if test 9423 -ne "`wc -c < 'label.c'`"
then
echo shar: "error transmitting 'label.c'" '(should have been 9423 characters)'
fi
fi
echo shar: "extracting 'number.c'" '(4039 characters)'
if test -f 'number.c'
then
echo shar: "will not over-write existing file 'number.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'number.c'
X/* Copyright (c) 1982, 1985 Gary Perlman */
X/* Copies can be made if not for material gain */
X
X/*
X number: report if a string is a UNIX formatted number
X
X notes:
X a number in UNIX is one that can be converted from
X a string to an integer or real with no loss of information
X due to bad format
X all numbers can be surrounded by whitespace
X an integer has an optional minus sign, followed by digits
X a real number has an optional minus sign followed by digits
X if a string has a decimal point, followed by zeros, it is real, not int
X
X value:
X 1 is string is an integer [-] 0-9+
X 2 is string is a real number (as seen by atof)
X 0 for non-numbers
X
X compilation flags:
X -DSTANDALONE includes test main program
X $Compile: cc -DSTANDALONE -O -o %F %f
X
X deficiencies:
X does not check to see if significant digits will be ignored
X
X author:
X Gary Perlman
X
X date:
X Wed May 22 13:30:40 EDT 1985
X Sun Sep 1 14:53:51 EDT 1985 (modified test module)
X
X*/
X#include <ctype.h>
X
X#ifndef lint
Xstatic char sccsfid[] = "@(#) number.c 5.2 (unix|stat) 9/1/85";
X#endif
X
X#define IS_NOT 0 /* not a number */
X#define IS_INT 1 /* an integer */
X#define IS_REAL 2 /* a real number */
X
X#define EOS '\0'
X
X/*LINTLIBRARY*/
X
Xnumber (string)
Xchar *string; /* the string to be tested */
X {
X int answer = IS_INT; /* start by assuming it is an integer */
X int before = 0; /* anything before the decimal? */
X int after = 0; /* anything after the decimal? */
X while (isspace (*string)) /* skip over blank space */
X string++;
X if (*string == EOS) /* empty string not allowed */
X return (IS_NOT);
X if (*string == '+' || *string == '-') /* old atoi didn't allow '+' */
X {
X string++;
X if (!isdigit (*string) && *string != '.')
X return (IS_NOT);
X }
X if (isdigit (*string)) /* note that there was a digit before . */
X {
X before = 1;
X while (isdigit (*string))
X string++;
X }
X if (*string == '.') /* found a decimal point, parse for real */
X {
X answer = IS_REAL;
X string++;
X if (isdigit (*string)) /* note that there was a digit after . */
X {
X after = 1;
X while (isdigit (*string))
X string++;
X }
X }
X if (!before && !after) /* must be digit somewhere */
X return (IS_NOT);
X if (*string == 'E' || *string == 'e') /* exponent */
X {
X answer = IS_REAL;
X string++;
X if (*string == '+' || *string == '-') /* optional sign */
X string++;
X if (!isdigit (*string)) /* missing exponent */
X return (IS_NOT);
X while (isdigit (*string))
X string++;
X }
X while (isspace (*string)) /* skip optional spaces */
X string++;
X /* should now have exhausted the input string */
X return (*string == EOS ? answer : IS_NOT);
X }
X
X#ifdef STANDALONE
X
X#include <stdio.h>
X/*
X exits with status = the number of args not numerical
X Shell Example:
X if number -i $*
X then
X echo processing $*
X else
X echo $0: arguments must be integers
X fi
X Options:
X -i arguments must be integer
X -n arguments must be non-negative
X*/
Xint NoNegative; /* do the values have to be non-negative? */
Xint Integer; /* do the values have to be integers? */
X
Xstatic
Xint
Xinitial (argc, argv) char **argv;
X {
X extern char *optarg;
X extern int optind;
X int errflg = 0;
X int C;
X char *optstring = "in";
X char *usage = "[-in] string ...";
X while ((C = getopt (argc, argv, optstring)) != EOF)
X switch (C)
X {
X case 'i': Integer = 1; break;
X case 'n': NoNegative = 1; break;
X default: errflg++; break;
X }
X if (errflg)
X {
X fprintf (stderr, "Usage: %s %s\n", argv[0], usage);
X exit (1);
X }
X return (optind);
X }
X
Xmain (argc, argv) char **argv;
X {
X int status = 0;
X int arg = initial (argc, argv);
X char *string;
X while (arg < argc)
X {
X string = argv[arg++];
X if (NoNegative && *string == '-') status++;
X else switch (number (string))
X {
X case IS_NOT: status++; break;
X case IS_REAL: if (Integer) status++; break;
X case IS_INT: break;
X default: /* CAN'T HAPPEN */ break;
X }
X }
X exit (status);
X }
X
X#endif
SHAR_EOF
if test 4039 -ne "`wc -c < 'number.c'`"
then
echo shar: "error transmitting 'number.c'" '(should have been 4039 characters)'
fi
fi
echo shar: "extracting 'filter.c'" '(4306 characters)'
if test -f 'filter.c'
then
echo shar: "will not over-write existing file 'filter.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'filter.c'
X/*
X Function: filter "Filter Command Line Files In Classic UNIX Style"
X Created: Sat Aug 10 21:57:12 EDT 1985
X By: Gary Perlman (Wang Institute, Tyngsboro, MA 01879 USA)
X Compilation: nothing unusual
X Tester: $Compile: cc -DSTANDALONE -o filter %f
X Preconditions:
X The index of the first file operand has been determined.
X Postconditions:
X All files have been opened, processed, and closed.
X Returns:
X The return status (non-zero is bad) depends on the accessibility
X of files, the ability to open them, and the return statuses of
X the called function.
X Exceptions:
X If any file cannot be accessed, then none will be processed.
X During processing, if something goes wrong (a file that could
X be accessed cannot be opened, or the file processor returns a
X non-zero status), processing continues.
X Notes:
X "-" is the conventional name for the standard input.
X It can only be read once.
X Fputs and putc are used to print error messages to avoid
X loading fat fprintf just because filter used it.
X*/
X
X
X#include <stdio.h>
X
X#ifdef STANDALONE
X
Xint
Xcat (file, ioptr)
Xchar *file;
Xregister FILE *ioptr;
X {
X register int C;
X while ((C = getc (ioptr)) != EOF)
X putchar (C);
X return (0);
X }
X
Xmain (argc, argv) char **argv;
X {
X int cat ();
X
X if (filter (argc, argv, 1, cat))
X {
X putc ('\007', stderr); /* UNIX friendly error message */
X exit (1);
X }
X exit (0);
X }
X
X#endif STANDALONE
X
X
X/* LINTLIBRARY */
Xstatic
Xvoid
Xerrmsg (pgm, file, errorno, dflt)
Xchar *pgm; /* name of the program running */
Xchar *file; /* file operand to be mentioned (if any) */
Xint errorno; /* system errno or some bad value */
Xchar *dflt; /* default message for bad error numbers */
X {
X extern char *sys_errlist[]; /* list of error messages */
X extern int sys_nerr; /* number of error messages */
X
X fputs (pgm, stderr);
X putc (':', stderr);
X putc (' ', stderr);
X if (errorno > 0 && errorno < sys_nerr)
X fputs (sys_errlist[errorno], stderr);
X else
X fputs (dflt, stderr);
X if (file)
X {
X putc (' ', stderr);
X putc ('\'', stderr);
X fputs (file, stderr);
X putc ('\'', stderr);
X }
X putc ('\n', stderr);
X }
X
X
X#define isstdin(file) (file[0] == '-' && file[1] == '\0')
X
Xint
Xfilter (argc, argv, curarg, process)
Xint argc; /* real number of command line args */
Xchar **argv; /* command line argument pointer */
Xint curarg; /* first argv to filter */
Xint (*process) (); /* status process (char *name, FILE *ioptr) */
X {
X int status = 0; /* return status of this function */
X int arg; /* loop index variable */
X char *file; /* name of the current file */
X char *pgm = argv[0]; /* name of the program */
X FILE *ioptr; /* file pointer for opening */
X int countstdin = 0; /* number of times stdin is processed */
X extern int errno; /* system error number */
X
X if (curarg == argc)
X status += ((*process) ("-", stdin));
X else
X {
X /* first check to make sure all files can be opened to read */
X for (arg = curarg; arg < argc; arg++)
X {
X file = argv[arg];
X if (isstdin (file))
X countstdin++;
X else if (access (file, 4))
X {
X errmsg (pgm, file, errno, "Can't access file");
X status++;
X }
X }
X if (countstdin > 1)
X {
X errmsg (pgm, NULL, -1, "Can only read standard input once");
X status++;
X }
X if (status == 0)
X for (arg = curarg; arg < argc; arg++)
X {
X file = argv[arg];
X if (isstdin (file))
X status += ((*process) (file, stdin) != 0);
X else if (ioptr = fopen (file, "r"))
X {
X status += ((*process) (file, ioptr) != 0);
X (void) fclose (ioptr);
X }
X else
X {
X errmsg (pgm, file, errno, "Can't open file");
X status++;
X }
X }
X }
X return (status);
X }
X
X/*NOTES
X Some modifications might be useful but unpopular:
X If there is piped input (!isatty (fileno (stdin))),
X and the standard input is not read,
X then some information may be ignored,
X so a warning should be printed.
X Unfortunately, this would break things like vi filters.
X
X If there is not piped input,
X and the standard input is being read from the keyboard,
X then prompt the user for input with something like:
X pgm: reading input from terminal
X This would avoid the problem of people forgetting to supply
X an input redirection.
X*/
SHAR_EOF
if test 4306 -ne "`wc -c < 'filter.c'`"
then
echo shar: "error transmitting 'filter.c'" '(should have been 4306 characters)'
fi
fi
echo shar: "extracting 'big_label'" '(294 characters)'
if test -f 'big_label'
then
echo shar: "will not over-write existing file 'big_label'"
else
sed 's/^ X//' << \SHAR_EOF > 'big_label'
X#!/bin/sh
X
XPATH=$PATH:/usr/ebin
Xexport PATH
X
X# make label pages for big labels 4.25 (50 spaces) x 2 (12 lines) inches
X
Xlabel -h 12 -s 2 -l 2 -w 50 -i 3 $* |
X ff -b -h "" -f "" -H 3 -F 3 | # put on a three line header/footer
X sed "s/ *$//" # remove trailing spaces
SHAR_EOF
if test 294 -ne "`wc -c < 'big_label'`"
then
echo shar: "error transmitting 'big_label'" '(should have been 294 characters)'
fi
chmod +x 'big_label'
fi
echo shar: "extracting 'small_label'" '(343 characters)'
if test -f 'small_label'
then
echo shar: "will not over-write existing file 'small_label'"
else
sed 's/^ X//' << \SHAR_EOF > 'small_label'
X#!/bin/sh
X
XPATH=$PATH:/usr/ebin
Xexport PATH
X
X# make label pages for small labels 2.75 (33 spaces) x 1 (6 lines) inch
X
Xlabel -h 6 -l 3 -w 33 -i 2 $* |
X ff -b -i 1 | # indent the lines one space
X sed "s/ *$//" # remove trailing spaces
X
X# you could use
X# sed "s/^/ /" instead of the faster ff call
SHAR_EOF
if test 343 -ne "`wc -c < 'small_label'`"
then
echo shar: "error transmitting 'small_label'" '(should have been 343 characters)'
fi
chmod +x 'small_label'
fi
echo shar: "extracting 'zipsort.c'" '(3999 characters)'
if test -f 'zipsort.c'
then
echo shar: "will not over-write existing file 'zipsort.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'zipsort.c'
X/*
X $Compile: cc -O -o %F %f
X*/
X#include <stdio.h>
X#include <ctype.h>
X#include <strings.h>
X
Xint Special = '\001'; /* magic char after sorting key */
X
Xtypedef int Status; /* return/exit status of functions */
X#define SUCCESS ((Status) 0)
X#define FAILURE ((Status) 1)
Xtypedef int Boole; /* no Boolean type in C */
X#define TRUE ((Boole) 1)
X#define FALSE ((Boole) 0)
X
XFILE *Pioptr; /* will pipe to sort and sed */
X
X/*FUNCTION main: loop through files in classic UNIX filter style */
Xmain (argc, argv)
Xint argc; /* argument count */
Xchar **argv; /* argument vector */
X {
X Status process (); /* process (file, ioptr) will filter files */
X Status status; /* return status of filter () */
X int firstfile; /* first file name index returned by initial */
X FILE *popen ();
X char command[BUFSIZ];
X
X firstfile = 1;
X
X sprintf (command, "sort | sed 's/^.*%c//'", Special);
X
X if (Pioptr = popen (command, "w"))
X {
X status = filter (argc, argv, firstfile, process);
X pclose (Pioptr);
X }
X else
X {
X fprintf (stderr, "%s: Can't run sorting pipeline\n", argv[0]);
X status = (-1);
X }
X exit (status);
X }
X
X#define iszipcode(s) \
X (!isdigit (s[-1]) \
X && isdigit (s[0]) \
X && isdigit (s[1]) \
X && isdigit (s[2]) \
X && isdigit (s[3]) \
X && isdigit (s[4]) \
X && !isdigit (s[5]))
X
Xprocess (file, ioptr)
Xchar *file;
XFILE *ioptr;
X {
X char line[BUFSIZ];
X char *ptr;
X int zipcode;
X
X while (fgets (ptr = line, BUFSIZ, ioptr))
X {
X zipcode = 0;
X for (ptr = line; *ptr; ptr++);
X while (ptr > line)
X if (iszipcode (ptr))
X {
X zipcode = atoi (ptr);
X break;
X }
X else ptr--;
X fprintf (Pioptr, "%05d%c%s", zipcode, Special, line);
X }
X }
X
Xstatic
Xvoid
Xerrmsg (pgm, file, errorno, dflt)
Xchar *pgm; /* name of the program running */
Xchar *file; /* file operand to be mentioned (if any) */
Xint errorno; /* system errno or some bad value */
Xchar *dflt; /* default message for bad error numbers */
X {
X extern char *sys_errlist[]; /* list of error messages */
X extern int sys_nerr; /* number of error messages */
X
X fputs (pgm, stderr);
X putc (':', stderr);
X putc (' ', stderr);
X if (errorno > 0 && errorno < sys_nerr)
X fputs (sys_errlist[errorno], stderr);
X else
X fputs (dflt, stderr);
X if (file)
X {
X putc (' ', stderr);
X putc ('\'', stderr);
X fputs (file, stderr);
X putc ('\'', stderr);
X }
X putc ('\n', stderr);
X }
X
X#define isstdin(file) (file[0] == '-' && file[1] == '\0')
X
Xint
Xfilter (argc, argv, curarg, process)
Xint argc; /* real number of command line args */
Xchar **argv; /* command line argument pointer */
Xint curarg; /* first argv to filter */
Xint (*process) (); /* status process (char *name, FILE *ioptr) */
X {
X int status = 0; /* return status of this function */
X int arg; /* loop index variable */
X char *file; /* name of the current file */
X char *pgm = argv[0]; /* name of the program */
X FILE *ioptr; /* file pointer for opening */
X int countstdin = 0; /* number of times stdin is processed */
X extern int errno; /* system error number */
X
X if (curarg == argc)
X status += ((*process) ("-", stdin));
X else
X {
X /* first check to make sure all files can be opened to read */
X for (arg = curarg; arg < argc; arg++)
X {
X file = argv[arg];
X if (isstdin (file))
X countstdin++;
X else if (access (file, 4))
X {
X errmsg (pgm, file, errno, "Can't access file");
X status++;
X }
X }
X if (countstdin > 1)
X {
X errmsg (pgm, NULL, -1, "Can only read standard input once");
X status++;
X }
X if (status == 0)
X for (arg = curarg; arg < argc; arg++)
X {
X file = argv[arg];
X if (isstdin (file))
X status += ((*process) (file, stdin) != 0);
X else if (ioptr = fopen (file, "r"))
X {
X status += ((*process) (file, ioptr) != 0);
X (void) fclose (ioptr);
X }
X else
X {
X errmsg (pgm, file, errno, "Can't open file");
X status++;
X }
X }
X }
X return (status);
X }
SHAR_EOF
if test 3999 -ne "`wc -c < 'zipsort.c'`"
then
echo shar: "error transmitting 'zipsort.c'" '(should have been 3999 characters)'
fi
fi
exit 0
# End of shell archive
--
Gary Perlman Wang Institute Tyngsboro, MA 01879 (617) 649-9731
UUCP: decvax!wanginst!perlman CSNET: perlman at wanginst
More information about the Comp.sources.unix
mailing list