v13i046: Program to make mailing labels
Rich Salz
rsalz at bbn.com
Wed Feb 17 11:28:31 AEST 1988
Submitted-by: Joe Chen <joec%wasat.usc.edu at OBERON.USC.EDU>
Posting-number: Volume 13, Issue 46
Archive-name: labels
LABELS is a label formatting program. It formats labels/mailing lists
according to user-defined label forms. This program has been fully
tested under Sun Unix 3.2 (BSD UNIX) and should work on any BSD UNIX
systems. It should also work under other UNIX systems with little
changes. As for non-Unix systems, like MS-DOS, you would need lex
and yacc for the PC, or obtain lex.yy.c and y.tab.* from an UNIX system.
Joe S. Chen
---------------------------------------------------------------------------
Phones at work: (213) 743-5363, (213) 743-5935; at home: (818) 571-5304
University Computing Services, University of Southern California
UUCP: {sdcrdcf, uscvax}!oberon!wasat!joec
ARPA: joec at wasat.usc.edu, joec at ecla.usc.edu
---------------------------------------------------------------------------
----------CUT HERE----------CUT HERE----------CUT HERE----------CUT HERE------
#!/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:
# INSTALL
# Makefile
# main.c
# labels.l
# labels.y
# labels.man
# 1083.lbl
# 1083f.lbl
# 1083t.lbl
# 6080.lbl
# 6080f.lbl
# 6080t.lbl
# 6083.lbl
# 6083f.lbl
# 6083t.lbl
export PATH; PATH=/bin:$PATH
echo shar: extracting "'INSTALL'" '(891 characters)'
if test -f 'INSTALL'
then
echo shar: over-writing existing file "'INSTALL'"
fi
cat << \SHAR_EOF > 'INSTALL'
Installation Procedure:
After extracting files from the shell archive, modify the following
variables in Makefile:
DESTDIR Destination directory, where the program
will be installed.
FRMDIR Directory (doesn't have to exist) where
pre-defined forms will reside.
LNAME Name of the program.
CFLAGS Define System where this program will
run under.
If you want to set a default form, you must edit the beginning
section of main.c.
To compile LABELS, type:
%make
and press carriage return. To install LABELS, type
%make install
and press carriage return, and the program and preset forms
will be installed in the proper directories. To install
the man page, you can simply copy the file 'labels.1' to
your man directory (e.g. /usr/man/man1).
To re-package labels, type
%make shar
and press return. The archived file 'labels.shar' will be the
new shell archive.
SHAR_EOF
echo shar: extracting "'Makefile'" '(2809 characters)'
if test -f 'Makefile'
then
echo shar: over-writing existing file "'Makefile'"
fi
cat << \SHAR_EOF > 'Makefile'
# -- MAKEFILE (UNIX) --
#
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @@ @@
# @@ Mailing List Label Formatter @@
# @@ Program Maintenance Specification @@
# @@ (C) Copyright 1987 by Joe Chen @@
# @@ All Rights Reserved @@
# @@ @@
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#
# Program created by Joe Chen - Jul 24, 1987
#
# *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
# Directory where LABELS is to be installed (please specify the full path)
DESTDIR = /usr/pollux/jchen/bin
# Directory where label forms can be found (please specify the full path)
FRMDIR = /usr/pollux/jchen/bin/lib
# Program name
LNAME = labels
# Compiling flags UNIX, BSD (USG and MSDOS are valid, but not fully supported)
# NOTE: This program has been fully tested on Sun UNIX only.
CFLAGS = -DBSD -DUNIX
CC = cc -c -g $(CFLAGS)
YACC = yacc
LEX = lex
LINK = cc
# *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
OBJS = y.tab.o lex.yy.o main.o
labels: $(OBJS)
@echo char \*rev_date = \"`date`\"\; > revdate.c
@echo Linking $(LNAME)...
@${LINK} $(OBJS) revdate.c -o $(LNAME)
@rm -f revdate.c revdate.o
@echo
@echo \`$(LNAME)\' Compiled.
y.tab.c: labels.y
@echo Running Yacc...
@${YACC} -d labels.y
y.tab.o: y.tab.c
@echo Compiling: y.tab.c
@${CC} y.tab.c
lex.yy.c: labels.l
@echo Running Lex...
@${LEX} labels.l
lex.yy.o: lex.yy.c y.tab.h
@echo Compiling: lex.yy.c
@${CC} lex.yy.c
main.o: main.c Makefile
@echo Compiling: main.c
@${CC} -DFDIR=\"$(FRMDIR)\" main.c
install:
@echo Installing \`$(LNAME)\' in $(DESTDIR)...
@rm -f $(DESTDIR/$(LNAME)
@cp $(LNAME) $(DESTDIR)/$(LNAME)
@strip $(DESTDIR)/$(LNAME)
@chmod 755 $(DESTDIR)/$(LNAME)
@echo
@echo Placing Form Definitions in $(FRMDIR)...
@echo mkdir $(FRMDIR) 2\> /dev/null \; exit 0 > mklib
@chmod u+x mklib
@./mklib
@rm -f mklib
@chmod 755 $(FRMDIR)
@cp *.lbl $(FRMDIR)
@chmod 644 $(FRMDIR)/*.lbl
@make man
@echo
@echo \`$(LNAME)\' installed.
clean:
@echo Cleaning Directory...
@rm -f *.o *\~ y.tab.* lex.yy.c $(LNAME)
@echo
@echo Done!
man:
@echo
@echo Processing a raw man page: $(LNAME).1
@/lib/cpp -P -DLIBDIR=$(FRMDIR) -DLNAME=$(LNAME) -DPROGDIR=$(DESTDIR) \
$(LNAME).man > $(LNAME).1
shar:
@echo Shell Archiving \($(LNAME)\.shar\)...
@shar INSTALL Makefile main.c labels.l labels.y labels.man \
*.lbl > $(LNAME).shar
@echo
@echo Done!
SHAR_EOF
echo shar: extracting "'main.c'" '(17102 characters)'
if test -f 'main.c'
then
echo shar: over-writing existing file "'main.c'"
fi
cat << \SHAR_EOF > 'main.c'
/* -- MAIN.C --
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ @@
@@ Mailing List Label Formatter @@
@@ Main Module @@
@@ (C) Copyright 1987 by Joe Chen @@
@@ All Rights Reserved @@
@@ @@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
You may freely distribute this software to others. But there are
few rules you must follow:
1. You don't profit from it. You may however ask for minimal fees to
cover shipping and handling.
2. This program is copyrighted, meaning you may not modify or enhance
this software and market it. You may make changes to suit your
local needs. Any enhancements are welcomed.
3. Please honor the author by not removing or replacing his name from
the source codes.
Feel free to contact me if you have any questions.
Joe Chen
---------------------------------------------------------------------------
Phones at work: (213) 743-5363, (213) 743-5935; at home: (818) 571-5304
University Computing Services, University of Southern California
UUCP: {sdcrdcf, uscvax}!oberon!wasat!joec
ARPA: joec at wasat.usc.edu, joec at ecla.usc.edu
---------------------------------------------------------------------------
Program created by Joe Chen - Jul 24, 1987
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
*/
/* Internal default form: 32x11x3 */
#define DEF_FORM "1083" /* form name here at USC */
#define ISTRING NULL /* initial escape sequence */
#define IFILL 12 /* fill n rows for adjustments */
#define FOFFS 0 /* form offset (from top) */
#define POFFS 0 /* page offset (from left) */
#define LWIDTH 32 /* width (in chars) of each label */
#define LHGAP 4 /* horizontal gap (in chars) between labels */
#define LVGAP 1 /* vertical gap (# of lines) between labels */
#define LCROSS 3 /* number of labels accross */
#define LMLINES 11 /* Maximum lines per label */
#define LOFFSET 4 /* offset (in chars) from left edge */
/* of each label */
#define LROWS 0 /* labels per page, 0=don't care*/
/*****************************************************************************/
#include <stdio.h>
#define QUIT (perror(argv[0]),dsp_usg(argv[0]),exit(-1))
#define FEXT ".lbl" /* file extension for form definition file */
#define GETC(x) (((ch=getc(x))=='\n')?line_num++,ch:ch);
#ifdef BSD
#include <sys/types.h>
#include <sys/dir.h>
#endif BSD
char *def_form = DEF_FORM; /* default label form */
char *def_istring = ISTRING; /* initial string/escape sequence */
char *l_istring;
int l_ifill = IFILL; /* Initial label fill for manual adjustments*/
int l_foffs = FOFFS; /* form offset (from top) */
int l_poffs = POFFS; /* page offset (from left) */
int l_width = LWIDTH; /* width of one label (in characters) */
int l_hgap = LHGAP; /* horizontal gap between labels (in chars) */
int l_vgap = LVGAP; /* vertical gap between labels (in chars) */
int l_cross = LCROSS; /* number of labels across one row */
int l_mlines= LMLINES; /* maximum printable lines per label */
int l_offset= LOFFSET; /* offset printing of data (in chars) */
int l_lrows = LROWS; /* rows of labels per page */
FILE *infile = stdin, *outfile = stdout;
int line_num = 1;
#define T 1
#define F 0
extern char *malloc(), *getcwd();
extern char *rev_date; /* supplied by Makefile */
extern FILE *yyin; /* from lex */
char *inpf = NULL, *outf = NULL; /* pointer to file names */
char *form = NULL; /* pointer to form name */
char **fmt_arry; /* line formatter */
char *version = "1.1";
#ifdef UNIX
#ifdef BSD
static char *os_title = "BSD UNIX Version";
#else
#ifdef USG
static char *os_title = "AT&T UNIX Version";
#endif USG
#endif BSD
#endif UNIX
#ifdef MSDOS
static char *os_title = "MS-DOS Verson";
#endif MSDOS
/****************************************************************************
dsp_usg() [Private function] - Display a brief usage info
parameters: name Name of this program
exit flags: none
****************************************************************************/
static void dsp_usg(name)
char *name;
{
printf("\nUsage: %s [-f <label form>] [<input file> [output file]]\n",
name);
printf(" or: %s -h\n", name);
#ifdef BSD
printf(" or: %s -l\n", name); /* list predefined forms */
#endif BSD
printf("\nWhere: <label form> is defined in %s,\n",FDIR);
printf(" or defined by user in the current directory.");
printf("\n <input file> is a text file containing raw labels.\n");
printf(" <output file> is the formatted label output.\n");
printf(" -h displays this help.\n");
printf(" -l lists all predefined forms.\n\n");
} /* dsp_usg() */
/****************************************************************************
list_forms() [Private function] - List predefined forms (BSD Unix only)
parameters: name program name (for error display purpose)
exit flags: none
****************************************************************************/
static void list_forms(name)
char *name;
{
#ifdef UNIX
#ifdef BSD
DIR *dirp; /* directory pointer */
struct direct *dp; /* pointer to a directory record */
char *ext_ptr; /* extension pointer */
char tmp[MAXNAMLEN+1], ch, *cur_dir;
int header = F;
FILE *f;
if ((dirp = opendir(FDIR)) == (DIR *)NULL) {
fprintf(stderr,"%s: Cannot Open Directory: %s\n",name, FDIR);
return;
}
if ((cur_dir = getcwd(NULL, 100)) == (char *)NULL) {
fprintf(stderr,"FATAL ERROR: Insufficient Memory\n");
exit(-1);
}
chdir(FDIR); /* change to directory containing the form defs */
for (dp = readdir(dirp); dp != (struct direct *)NULL; dp = readdir(dirp)) {
if (strlen(dp->d_name) <= strlen(FEXT))
continue;
ext_ptr = &dp->d_name[strlen(dp->d_name)-strlen(FEXT)];
if (!strcmp(ext_ptr, FEXT)) { /* must have the same extension */
(void) strcpy(tmp, dp->d_name);
/* ignore extension */
tmp[strlen(tmp)-strlen(FEXT)] = '\0';
if (!header) {
fprintf(stderr,"Preset Forms\tRemarks\n");
fprintf(stderr,"------------\t-------\n");
header = T;
}
/* print out the name of the form */
fprintf(stderr,"%s\t\t", tmp);
if ((f=fopen(dp->d_name,"r")) == (FILE *)NULL)
fprintf(stderr,"(Form Unreadable)\n");
else {
/* Display the first line, if it is a remark */
if (getc(f) != '#')
fprintf(stderr,"(No Remark)\n");
else {
while ((ch=getc(f)) == ' '); /* skip leading spaces */
ungetc(ch, f);
while ((ch=getc(f)) != '\n') {
putc(ch, stderr); /* print comment */
if (feof(f))
break;
} /* keep reading info */
fprintf(stderr,"\n");
} /* display a line of info */
fclose(f);
} /* query file */
}
} /* for all entries */
chdir(cur_dir); /* change back the directory */
free(cur_dir);
#endif BSD
#ifdef USG
/* System V listing: for now, just use ls */
char cmd[100];
(void) sprintf(cmd, "/bin/ls %s/*%s", FDIR, FEXT);
(void) system(cmd);
#endif USG
#endif UNIX
#ifdef MSDOS
fprintf(stderr,"Not implemented at this time for MSDOS\n");
#endif MSDOS
} /* list_forms() */
/****************************************************************************
get_record() [Private function] - Reads one label info into internal buffer
parameters: rec Buffer for holding one label record
exit flags: 0 end-of-file or no label between periods
>0 number of lines read for this label
****************************************************************************/
static int get_record(rec)
char **rec;
{
char ch, *p;
int i = 0, j;
do {
p = rec[i]; /* next line */
/* read in one line */
for (j = 0, p[j] = '\0'; ; j++) {
if (!feof(infile)) {
if (j > (l_width-l_offset)) { /* line too long */
fprintf(stderr,"Line %d: Line too long (%d) - Truncated\n",
line_num, l_width);
p[l_width-l_offset] = '\0'; /* force termination */
while (getc(infile) != '\n')
if (feof(infile))
return i;
line_num++;
break;
} /* line too long */
if ((p[j]=getc(infile)) == '\n') { /* read in next char */
line_num++;
p[j] = '\0';
break;
} /* if end-of-line, go read next line */
if ((!j)&&(p[j]=='.')) { /* end of label */
while (getc(infile) != '\n')
if (feof(infile))
break; /* end of file */
line_num++;
return i; /* return lines read */
} /* end of label detected */
}
else
return i;
} /* for */
} while (++i < l_mlines);
if ((ch=getc(infile)) != '.')
fprintf(stderr,"Line %d: Lines Exceeded Limit (%d) - Ignoring the Rest\n",
line_num,l_mlines);
ungetc(ch, infile);
/* truncating... */
while (1) {
if (getc(infile) == '.') { /* at the end already */
while(getc(infile) != '\n')
if (feof(infile))
break;
line_num++;
return i;
} /* skip to next label */
while(getc(infile) != '\n')
if (feof(infile))
return i;
line_num++;
}
} /* get_record() */
/****************************************************************************
main() [Public function] - Startup routine
parameters: argc Number of command-line arguments
argv argument array
exit flags: 0 Program terminate normally
<>0 Error (of some sort) occurred, program aborted
****************************************************************************/
main(argc, argv)
int argc;
char **argv;
{
char **row, **rec, *p, *tmpbuf;
int arg_limit = 3; /* argument handler (too hard to explain) */
register i, j, k, l;
int cur_col, lines, started = F, row_count;
FILE *ffile; /* to read form file */
l_istring = def_istring;
if (argc > 1) {
/* get brief usage */
if ((!strcmp(argv[1], "help"))||(!strcmp(argv[1], "-h"))) {
dsp_usg(argv[0]);
exit(0);
}
/* list defined forms in FDIR */
if (!strcmp(argv[1], "-l")) {
list_forms(argv[0]);
exit(0);
}
} /* check for single argument */
fprintf(stderr,
"LABELS: Label/Mailing List Formatter - %s\n", os_title);
fprintf(stderr,"Release %s - Compiled %s\n\n", version, rev_date);
form = def_form;
/* allocate space to hold data format for each line */
if ((fmt_arry = (char **) malloc(l_mlines*sizeof(char *))) ==(char **)NULL)
QUIT;
for (i=l_mlines; i ; i--) {
fmt_arry[i-1] = malloc(l_width+1);
if (fmt_arry[i-1] == (char *)NULL)
QUIT;
(void) strcpy(fmt_arry[i-1], "%s"); /* default format, data only */
}
if (argc < 2)
goto ckarg;
/* Check if user specified his/her own form */
if (!strcmp(argv[1], "-f")) {
char *frm_name;
if (argc == 2) {
fprintf(stderr,"%s: Form name is missing!\n",argv[0]);
exit(-1);
}
/* Make a complete file name for form */;
frm_name = malloc(strlen(FDIR)+strlen(argv[2]+strlen(FEXT)+2));
if (frm_name == (char *)NULL)
QUIT;
arg_limit += 2;
form = argv[2];
/* create a path to open the label form file */
(void) strcpy(frm_name, FDIR);
#ifdef MSDOS
(void) strcat(frm_name, "\\");
#else
(void) strcat(frm_name, "/");
#endif MSDOS
(void) strcat(frm_name, form);
(void) strcat(frm_name, FEXT); /* form extension */
/* open file */
if ((ffile=fopen(frm_name, "r")) == (FILE *)NULL) {
/* trouble opening file from library directory, try current directory */
(void) strcpy(frm_name, ".");
#ifdef MSDOS
(void) strcat(frm_name, "\\");
#else
(void) strcat(frm_name, "/");
#endif MSDOS
(void) strcat(frm_name, form);
(void) strcat(frm_name, FEXT); /* form extension */
if ((ffile=fopen(frm_name, "r")) == (FILE *)NULL) {
/* cannot open file in current directory either, give up */
fprintf(stderr,"%s: Cannot read form: %s\n",*argv,form);
exit(-1);
}
} /* open form */
yyin = ffile;
/* now parse the file */
if (yyparse()) {
fprintf(stderr,"%s: Error reading form: %s\n",*argv,form);
exit(-1);
}
free(frm_name);
} /* reading form definitions */
ckarg:
/* Check if there are too many arguments */
if (argc > arg_limit) {
fprintf(stderr,"%s: Too many arguments\n", argv[0]);
exit(-1);
}
/* Check if output file is given (has to be the last argument) */
if (argc > arg_limit-1) {
if ((outfile = fopen(argv[arg_limit-1], "w")) == (FILE *)NULL)
QUIT;
outf = argv[arg_limit-1];
}
/* Check if input file is given (second to the last argument) */
if (argc > arg_limit-2) {
if ((infile = fopen(argv[arg_limit-2],"r")) == (FILE *)NULL)
QUIT;
inpf = argv[arg_limit-2];
}
/* allocate space to hold a row of labels of n across */
if ((row = (char **) malloc(l_mlines*sizeof(char *))) == (char **)NULL)
QUIT;
for (i=l_mlines; i ; i--) {
row[i-1] = malloc(l_width*l_cross+l_hgap*(l_cross-1)+100);
if (row[i-1] == (char *)NULL)
/* insufficient memory */
QUIT;
} /* for */
fprintf(stderr,"[Input: %s, Output: %s, Form: %s]\n",
(inpf!=(char *)NULL)?inpf:"(stdin)",
(outf!=(char *)NULL)?outf:"(stdout)", form);
/* allocate space to hold one label of n lines */
if ((rec = (char **) malloc((l_mlines+1)*sizeof(char *))) == (char **)NULL)
QUIT;
for (i=l_mlines+1; i ; i--) /* buffer space should be big */
if ((rec[i-1] = malloc(l_width*2)) == (char *)NULL)
QUIT;
/* for formatting purpose */
if ((tmpbuf = malloc(l_width*2)) == (char *)NULL)
QUIT;
row_count = l_lrows + 1; /* ensure checking for form offset */
/* main loop */
while(T) {
/* clear one row of labels*/
for (i = 0; i < l_mlines; i++)
for (j = 0, k = (l_width*l_cross+l_hgap*(l_cross-1)); j < k ; j++)
row[i][j] = ' ';
for (cur_col=0; cur_col < l_cross; cur_col++) {
while (!(lines=get_record(rec))) /* get one label from input */
if (feof(infile)) { /* if no lines read, probably eof */
if (cur_col)
goto f; /* flush output */
goto d; /* quit */
}
/* Check each input line with format string */
for (i = 0; i < lines; i++) {
if (!strcmp(fmt_arry[i], "%s"))
continue; /* no need to format, use default */
(void) strcpy(tmpbuf,rec[i]);
(void) sprintf(rec[i],fmt_arry[i],tmpbuf);
/* truncate if string too long after formatting */
if (strlen(rec[i]) > (l_width-l_offset)) {
rec[i][(l_width-l_offset)] = '\0';
fprintf(stderr,
"Line %d: Line too long after formatting (%d) - Truncated\n",
line_num-lines-1+i, l_width);
} /* string too long after formatting */
}
for (i = j = (l_mlines-lines)/2, k = 0; i < (j+lines); i++, k++) {
p = (char *) ((int)row[i] + cur_col*(l_width+l_hgap) + l_offset);
for (l = 0; rec[k][l]; l++)
p[l] = rec[k][l];
} /* fill n lines for one label */
} /* for one row */
f:
if (!started) {
/* Output initial string or escape sequence to printer */
started = T;
if (l_istring != (char *)NULL)
fprintf(outfile, l_istring);
if (l_ifill) {
int kk;
/* fills n rows for manual adjustment purposes */
for (i = 0; i < l_ifill; row_count++, i++) {
if ((row_count < l_lrows)||(!l_lrows))
kk = 0;
else {
kk = l_foffs;
row_count = 0;
}
for (; kk < l_mlines; putc('\n', outfile), kk++) {
for (j = 0; j < l_cross; j++) {
for (k = l_poffs; k < l_width; k++)
putc('#', outfile); /* fill one line of a label */
if (j < l_cross-1)
for (k = 0; k < l_hgap; k++)
fprintf(outfile," "); /* make horizontal gaps */
} /* for one line in label */
} /* for one row of label */
for (k = 0; k < l_vgap; putc('\n', outfile), k++);
} /* for n rows */
} /* if need to adjust */
} /* if initial output */
/* print row to output file */
if ((row_count < l_lrows)||(!l_lrows))
i = 0; /* print entire label */
else {
/* if there's a form offset, the first row of labels maybe truncated */
i = l_foffs;
row_count = 0;
}
for (k = (l_width*l_cross+l_hgap*(l_cross-1)); i < l_mlines; i++) {
/* set an absolute length for output */
row[i][k] = '\0';
/* if there's a page offset, we better look out */
fprintf(outfile,"%s\n", &row[i][l_poffs]);
}
/* fill vertical gap */
for (i = 0; i < l_vgap; i++)
putc('\n', outfile);
row_count++;
} /* process entire file - while() */
d:
if (infile != stdin)
fclose(infile);
if (outfile != stdout)
fclose(outfile);
fprintf(stderr,"\n%s: Formatting Complete\n",argv[0]);
} /* main() */
SHAR_EOF
echo shar: extracting "'labels.l'" '(3284 characters)'
if test -f 'labels.l'
then
echo shar: over-writing existing file "'labels.l'"
fi
cat << \SHAR_EOF > 'labels.l'
%{
/* -- LABELS.L --
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ @@
@@ Mailing List Label Formatter @@
@@ Lexical Analyzer for Form Parsing @@
@@ (C) Copyright 1987 by Joe Chen @@
@@ All Rights Reserved @@
@@ @@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
You may freely distribute this software to others. But there are
few rules you must follow:
1. You don't profit from it. You may however ask for minimal fees to
cover shipping and handling.
2. This program is copyrighted, meaning you may not modify or enhance
this software and market it. You may make changes to suit your
local needs. Any enhancements are welcomed.
3. Please honor the author by not removing or replacing his name from
the source codes.
Feel free to contact me if you have any questions.
Joe Chen
---------------------------------------------------------------------------
Phones at work: (213) 743-5363, (213) 743-5935; at home: (818) 571-5304
University Computing Services, University of Southern California
UUCP: {sdcrdcf, uscvax}!oberon!wasat!joec
ARPA: joec at wasat.usc.edu, joec at ecla.usc.edu
---------------------------------------------------------------------------
Program created by Joe Chen - Jul 24, 1987
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
*/
#include <stdio.h>
#ifdef UNIX
#include "y.tab.h"
#else
#include "ytab.h"
#endif
int value, line_no = 1;
extern char *form;
%}
cr \n
tab \t
space " "
white_space ({space}|{tab})
spcs {white_space}*
digit [0-9]
number {digit}+
letter [A-Za-z_]
word {letter}({letter}|{digit})*
%%
{spcs} ;
#.* ;
{cr} { line_no++; }
initial { return(_INITIAL); }
string { return(_KSTRING); }
fill { return(_FILL); }
form { return(_FORM); }
page { return(_PAGE); }
width { return(_WIDTH); }
hgap { return(_HGAP); }
vgap { return(_VGAP); }
columns { return(_COLUMNS); }
column { return(_COLUMNS); }
format { return(_FORMAT); }
offset { return(_OFFSET); }
of { return(_OF); }
for { return(_OF); }
lines { return(_LINES); }
line { return(_LINE); }
rows { return(_ROWS); }
is { return(_IS); }
"," { return(_DELIM); }
";" { return(_DELIM); }
"=" { return(_ASSIGN); }
":" { return(_ASSIGN); }
{number} {
value = atoi(yytext);
return(_VALUE);
}
{word} { return(_WORD); }
\"[^\"]*\" { return(_STRING); }
. {
fprintf(stderr,
"Line %d in %s: Illegal Character: '%s'\n",
line_no, yytext);
}
%%
/****************************************************************************
yywrap() [Public function] - lex's function when EOF is detected from yyin
parameters: none
exit flags: 1 Done matching tokens from input file
****************************************************************************/
yywrap()
{
return 1;
} /* yywrap() */
SHAR_EOF
echo shar: extracting "'labels.y'" '(5508 characters)'
if test -f 'labels.y'
then
echo shar: over-writing existing file "'labels.y'"
fi
cat << \SHAR_EOF > 'labels.y'
%{
/* -- LABELS.Y --
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ @@
@@ Mailing List Label Formatter @@
@@ Syntax Analyzer for Form Parsing @@
@@ (C) Copyright 1987 by Joe Chen @@
@@ All Rights Reserved @@
@@ @@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
You may freely distribute this software to others. But there are
few rules you must follow:
1. You don't profit from it. You may however ask for minimal fees to
cover shipping and handling.
2. This program is copyrighted, meaning you may not modify or enhance
this software and market it. You may make changes to suit your
local needs. Any enhancements are welcomed.
3. Please honor the author by not removing or replacing his name from
the source codes.
Feel free to contact me if you have any questions.
Joe Chen
---------------------------------------------------------------------------
Phones at work: (213) 743-5363, (213) 743-5935; at home: (818) 571-5304
University Computing Services, University of Southern California
UUCP: {sdcrdcf, uscvax}!oberon!wasat!joec
ARPA: joec at wasat.usc.edu, joec at ecla.usc.edu
---------------------------------------------------------------------------
Program created by Joe Chen - Jul 24, 1987
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
*/
#include <stdio.h>
extern char *malloc(), *realloc();
extern int value, line_no;
extern char yytext[], **fmt_arry, *l_istring;
extern int l_width, l_hgap, l_vgap, l_columns, l_mlines, l_offset, l_cross;
extern int l_ifill, l_foffs, l_poffs, l_lrows;
extern FILE *form;
%}
%union {
int vars;
};
%token _INITIAL
%token _KSTRING
%token _FORM
%token _PAGE
%token _FILL
%token _WIDTH
%token _HGAP
%token _VGAP
%token _COLUMNS
%token _LINES
%token _ROWS
%token _OFFSET
%token _FORMAT
%token _OF
%token _LINE
%token _IS
%token _ASSIGN
%token _DELIM
%token _VALUE
%token _STRING
%token _WORD
%type <vars> variable
%%
cmd : stmts
;
stmts : stmts delim stmt
| stmt
;
delim : _DELIM delim
|
;
stmt : param_stmt_val
| fmt_stmt
| init_stmt
;
param_stmt_val : variable is _VALUE
{
switch($1) {
case _WIDTH:
l_width = value;
break;
case _HGAP:
l_hgap = value;
break;
case _VGAP:
l_vgap = value;
break;
case _COLUMNS:
l_cross = value;
break;
case _LINES: {
if (l_mlines < value) {
int i; /* need to adjust format buffer */
fmt_arry=(char **)realloc(fmt_arry,value*sizeof(char *));
if (fmt_arry == (char **)NULL)
goto e;
/* add new format lines */
for (i=l_mlines; i < value; i++) {
fmt_arry[i] = malloc(l_width+1);
if (fmt_arry[i] == (char *)NULL)
goto e;
(void) strcpy(fmt_arry[i], "%s");
}
} /* adjust the format buffer */
l_mlines = value;
break;
e:
fprintf(stderr,"Fatal Error: Insufficient Memory\n");
exit(-1);
}
case _OFFSET:
/* label column offset */
l_offset = value;
break;
case _FORM:
/* form offset value */
l_foffs = value;
break;
case _PAGE:
/* page offset value */
l_poffs = value;
break;
case _ROWS:
/* rows per label */
l_lrows = value;
break;
} /* set various variables */
}
;
variable : _WIDTH
{
$$=_WIDTH;
}
| _HGAP
{
$$=_HGAP;
}
| _VGAP
{
$$=_VGAP;
}
| _COLUMNS
{
$$=_COLUMNS;
}
| _LINES
{
$$=_LINES;
}
| _LINE
{
$$=_LINES;
}
| _ROWS
{
$$=_ROWS;
}
| _OFFSET
{
$$=_OFFSET;
}
| _FORM _OFFSET
{
$$=_FORM;
}
| _PAGE _OFFSET
{
$$=_PAGE;
}
| _WORD
{
$$=0;
fprintf(stderr,"Line %d in %s: Unknown variable: %s\n",
line_no, form, yytext);
}
;
fmt_stmt : _FORMAT _OF line _VALUE is _STRING
{
if (value > l_mlines) {
fprintf(stderr,"Line %d in %s: Line Number Execeeded ",
line_no, form);
fprintf(stderr,"Maximum (%d); Format Ignored\n",l_mlines);
}
else {
/* supercede format */
(void) strcpy(fmt_arry[value-1], &yytext[1]);
/* remove quotes */
fmt_arry[value-1][strlen(fmt_arry[value-1])-1] = '\0';
}
}
;
init_stmt : _INITIAL _KSTRING is _STRING
{
if ((l_istring = malloc(strlen(yytext))) == (char *)NULL) {
fprintf(stderr,"Fatal Error: Insufficient Memory\n");
exit(-1);
}
/* remove the quotations */
(void) strcpy(l_istring, &yytext[1]);
l_istring[strlen(l_istring)-1] = '\0';
}
| _INITIAL _FILL is _VALUE
{
/* initial fill value */
l_ifill = value;
}
;
line : _LINE
|
;
is : _IS
| _ASSIGN
|
;
%%
/****************************************************************************
yyerror() [Public function] - Yacc error trap function
parameters: s Error message from yacc's LR driver
exit flags: none
****************************************************************************/
yyerror(s)
char *s;
{
if (strcmp(s, "syntax error"))
fprintf(stderr,"Line %d in %s: %s\n",line_no,form,s);
} /* yyerror() */
SHAR_EOF
echo shar: extracting "'labels.man'" '(7344 characters)'
if test -f 'labels.man'
then
echo shar: over-writing existing file "'labels.man'"
fi
cat << \SHAR_EOF > 'labels.man'
.pl 60
.\" Man Page for LABELS
.TH LABELS 1 "2 Aug 1987"
.SH NAME
labels \- produce formatted output for label printing
.SH SYNOPSIS
.B LNAME
[
.B \-f <form>
]
[
.B <input file>
[
.B <output file>
] ]
.br
.B LNAME
.B \-h
.br
.B LNAME
.B \-l
.SH DESCRIPTION
.B LNAME accepts a raw
.B <input file>
and produces a formatted
.B <output file>.
If
.B <output file>
is not specified, then formatted output will
go to standard output
.I (stdout).
If
.B <input file>
is not specified in addition to the omission of
.B <output file>,
then input will be taken from the standard input
.I (stdin).
.sp
.\" describe the format of the input file
The format of an input file is simple and straight forward. The
following is an example:
.nf
.sp
John Doe
123 Main St.
City of DownUnder, AU 9999
.
Susan Smith
Label Products, Inc.
1000 Broadway Blvd.
Space City, DD 00001
.
.sp
.fi
A period "." must be placed at the beginning of a new line
after completing data input for each label.
.\" describe the format of label forms
.sp
By default,
.B LNAME
prepares the output for USC-UCC standard label form (1083), which is 32 characters
wide and 11 lines long per label, and 3 labels across. The optional
.B \-f <form>
can be used to overcome the default label format. A directory
of preset label formats can be listed by specifying the
.B \-l
parameter alone. If a desired form is not available, the user
can define one, like the following:
.sp
.nf
# Standard label size (32 char x 6 lines, 3 columns)
width = 32, lines = 6, columns = 3
# other alignments
hgap = 4, vgap = 1, offset = 4
.fi
.sp
A line that starts with # is treated as a comment. Various
parameters can be set by specifying the variable name, like
.I width,
and assign it to the a value, like 32. The above form file
defines the following:
.sp
.nf
\- Each label has maximum width of 32 characters (width=32).
\- Each label has maximum lines of 6 (lines=6).
\- Format for 3 labels across (columns=3).
\- Set horizontal gap between labels to be 4 characters (hgap=4).
\- Set vertical gap between labels to be 1 line (vgap=1).
\- Set data offset to be 4 characters from the left (offset=4).
.fi
.sp
You may also use the
.B :
or a space in the place of
.B =.
In other words, you can use any one of the variations:
.sp
.nf
width:32 width 32 or width = 32.
.fi
.sp
Also, you may use a semicolon in place of a comma.
.sp
There is a naming convention for such file. Each form definition
file
.B must
have the extension
.B .lbl
and must be in the current directory in order for it to be
recognized by
.B LNAME.
For example, the above definition may be placed in
a file called
.I myform.lbl.
To format labels from an input file
.I labels.in
and save the formatted output to
.I labels.out
using
.I myform.lbl,
type:
.sp
.nf
LNAME -f myform labels.in labels.out
.fi
.sp
.B LNAME
will search for
.I myform
from a set of preset forms. If such form does not exist, it
will then search in user's current directory.
.sp
Many people prefer to print mailing list labels with a "To:"
attached to the first line, and the rest of the lines must
align properly. The user may create the following form:
.sp
.nf
# Standard label size (32 char x 6 lines, 3 columns) with "To:"
lines:6; width:32
columns:2
# other alignments
hgap:4; vgap:1; offset:0
# format definition for each of the 6 lines in a label
format for line 1 is " To: %s"
format for line 2 is " %s"
format for line 3 is " %s"
format for line 4 is " %s"
format for line 5 is " %s"
format for line 6 is " %s"
.fi
.sp
If the sample input data file on page 1 is used, along with the above
form, this is the result:
.nf
.sp
-----------------------------------------------------------------------
| | | |
| To: John Doe | | To: Susan Smith |
| 123 Main St. | | Label Products, Inc. |
| City of DownUnder, AU 9999 | | 1000 Broadway Blvd. |
| | | Space City, DD 00001 |
| | | |
-----------------------------------------------------------------------
.fi
.sp
The string
.I %s
is substituted with the input data. Thus by default, each line has
the format of "%s".
If "To:" is desired to be added to the first line, like to above example,
then the format for the first line can be defined as "To: %s".
.sp
Customized printing of labels can also be done. Initial string of
escape sequences can be sent via the
.I "initial string"
command:
.sp
.nf
initial string = "^[B"
.fi
.sp
where
.I "^[B"
could be an escape sequence to enable bold printing on a particular
printer.
.sp
Another useful parameter is
.I "initial fill."
Before printing labels on a line printer, the operator often needs
to re-adjust the printer. By printing the dimensions of the label
forms, the printer can be adjusted properly before printing the
first valid label. To fill ten rows of labels initially, the
following parameter is specified in the form definition:
.sp
.nf
initial fill = 10
.fi
.sp
Finally, if you need a quick reminder about the program parameters,
a brief command usage can be reviewed by specifying the
.I \-h
parameter alone.
.SH LIMITATIONS
LNAME assumes that the printer to be used is using a font with
constant widths for all characters.
.SH FILES
PROGDIR/LNAME
.sp
All .lbl files in LIBDIR are predefined label form definitions.
A listing can be obtained by specifying the
.B \-l
parameter.
.SH DIAGNOSIS
Below is a list of common error messages and their descriptions.
.sp
.B "Line xxxx: Line too long (x) - Truncated"
.sp
Length of the input data at line xxxx is longer than the maximum
defined width of x. The rest of the input on that line is truncated.
.sp
.B "Line xxxx: Line too long after formatting (x) - Truncated"
.sp
The length of the formatted string at line xxxx is longer than the
maximum width permitted, which is x.
.sp
.B "Line xxxx: Lines Exceeded Limit (x) - Ignoring the Rest"
.sp
Number of lines per label is greater than the maximum of x lines.
.sp
.B LNAME
.B ": Cannot read form:"
.I form
.sp
The form you specified with
.B \-f
is not found. The file name must have the extension .lbl.
.sp
.B LNAME
.B ": Error reading form:"
.I form
.sp
User defined form has improper syntax, which resulted in parsing
errors. Various parsing errors are also displayed.
.sp
.B LNAME
.B ": Too many arguments"
.sp
Too many arguments specified. A brief program usage is displayed.
.sp
.B LNAME
.B ": Cannot Open Directory:"
.I dir
.sp
Cannot list preset forms because the directory containing form files
does not exist.
.sp
.SH BUGS
None discovered so far. Please report any bugs you may find
to the author by electronic mail.
.SH AUTHOR
.nf
Joe S. Chen, Consultant, UNIX, VMS, and TOPS-20
Phones: (213) 743-5363, (213) 743-5935
University Computing Services, University of Southern California
UUCP: {sdcrdcf, uscvax}!oberon!wasat!joec
ARPA: joec at wasat.usc.edu, joec at ecla.usc.edu
.fi
SHAR_EOF
echo shar: extracting "'1083.lbl'" '(259 characters)'
if test -f '1083.lbl'
then
echo shar: over-writing existing file "'1083.lbl'"
fi
cat << \SHAR_EOF > '1083.lbl'
# Form 1083 (32 chars x 11 lines, 3 cols) for line printing
# Last changed: 8/3/87 by Joe. Chen, USC-UCC
initial fill = 12 # our operators need a lot of time to adjust!
width = 32, lines = 11, columns = 3
# other alignments
hgap = 4; vgap = 1, offset = 4
SHAR_EOF
echo shar: extracting "'1083f.lbl'" '(548 characters)'
if test -f '1083f.lbl'
then
echo shar: over-writing existing file "'1083f.lbl'"
fi
cat << \SHAR_EOF > '1083f.lbl'
# Same as Form 1083 with "From:"
# Last changed: 8/3/87 by Joe. Chen, USC-UCC
initial fill = 12
width = 32, lines = 11, columns = 3
# other alignments
hgap = 4, vgap = 1, offset = 0
# Reformat each line
format of line 1 : "From: %s"
format of line 2 : " %s"
format of line 3 : " %s"
format of line 4 : " %s"
format of line 5 : " %s"
format of line 6 : " %s"
format of line 7 : " %s"
format of line 8 : " %s"
format of line 9 : " %s"
format of line 10 : " %s"
format of line 11 : " %s"
SHAR_EOF
echo shar: extracting "'1083t.lbl'" '(524 characters)'
if test -f '1083t.lbl'
then
echo shar: over-writing existing file "'1083t.lbl'"
fi
cat << \SHAR_EOF > '1083t.lbl'
# Same as Form 1083 with "To:"
# Last changed: 8/3/87 by Joe. Chen, USC-UCC
initial fill : 12
width : 32, lines : 11, columns : 3
# other alignments
hgap : 4, vgap : 1, offset : 1
# Reformat each line
format of line 1 : "To: %s"
format of line 2 : " %s"
format of line 3 : " %s"
format of line 4 : " %s"
format of line 5 : " %s"
format of line 6 : " %s"
format of line 7 : " %s"
format of line 8 : " %s"
format of line 9 : " %s"
format of line 10 : " %s"
format of line 11 : " %s"
SHAR_EOF
echo shar: extracting "'6080.lbl'" '(209 characters)'
if test -f '6080.lbl'
then
echo shar: over-writing existing file "'6080.lbl'"
fi
cat << \SHAR_EOF > '6080.lbl'
# Xerox 6080 (34 chars x 6 lines, 3 cols) for laser printing
# Last changed: 8/2/87 by Joe. Chen, USC-UCC
initial fill = 0
width = 34, lines = 6, columns = 3
# other alignments
hgap 0; vgap : 0, offset = 2
SHAR_EOF
echo shar: extracting "'6080f.lbl'" '(391 characters)'
if test -f '6080f.lbl'
then
echo shar: over-writing existing file "'6080f.lbl'"
fi
cat << \SHAR_EOF > '6080f.lbl'
# Same as Form 6080 with "From:"
# Last changed: 8/2/87 by Joe. Chen, USC-UCC
initial fill = 0
width = 34, lines = 6, columns = 3
# other alignments
hgap = 0, vgap = 0, offset = 0
# Reformat each line
format of line 1 : "From: %s"
format of line 2 : " %s"
format of line 3 : " %s"
format of line 4 : " %s"
format of line 5 : " %s"
format of line 6 : " %s"
SHAR_EOF
echo shar: extracting "'6080t.lbl'" '(377 characters)'
if test -f '6080t.lbl'
then
echo shar: over-writing existing file "'6080t.lbl'"
fi
cat << \SHAR_EOF > '6080t.lbl'
# Same as Form 1083 with "To:"
# Last changed: 8/2/87 by Joe. Chen, USC-UCC
initial fill : 0
width : 34, lines : 6, columns : 3
# other alignments
hgap : 0, vgap : 0, offset : 0
# Reformat each line
format of line 1 : "To: %s"
format of line 2 : " %s"
format of line 3 : " %s"
format of line 4 : " %s"
format of line 5 : " %s"
format of line 6 : " %s"
SHAR_EOF
echo shar: extracting "'6083.lbl'" '(209 characters)'
if test -f '6083.lbl'
then
echo shar: over-writing existing file "'6083.lbl'"
fi
cat << \SHAR_EOF > '6083.lbl'
# Xerox 6083 (34 chars x 9 lines, 3 cols) for laser printing
# Last changed: 8/3/87 by Joe. Chen, USC-UCC
initial fill = 0
width = 34, lines = 9, columns = 3
# other alignments
hgap 0; vgap : 0, offset = 2
SHAR_EOF
echo shar: extracting "'6083f.lbl'" '(453 characters)'
if test -f '6083f.lbl'
then
echo shar: over-writing existing file "'6083f.lbl'"
fi
cat << \SHAR_EOF > '6083f.lbl'
# Same as Form 6083 with "From:"
# Last changed: 8/2/87 by Joe. Chen, USC-UCC
initial fill = 0
width = 34, lines = 9, columns = 3
# other alignments
hgap = 0, vgap = 0, offset = 0
# Reformat each line
format of line 1 : "From: %s"
format of line 2 : " %s"
format of line 3 : " %s"
format of line 4 : " %s"
format of line 5 : " %s"
format of line 6 : " %s"
format of line 7 : " %s"
format of line 8 : " %s"
SHAR_EOF
echo shar: extracting "'6083t.lbl'" '(435 characters)'
if test -f '6083t.lbl'
then
echo shar: over-writing existing file "'6083t.lbl'"
fi
cat << \SHAR_EOF > '6083t.lbl'
# Same as Form 6083 with "To:"
# Last changed: 8/2/87 by Joe. Chen, USC-UCC
initial fill : 0
width : 34, lines : 9, columns : 3
# other alignments
hgap : 0, vgap : 0, offset : 0
# Reformat each line
format of line 1 : "To: %s"
format of line 2 : " %s"
format of line 3 : " %s"
format of line 4 : " %s"
format of line 5 : " %s"
format of line 6 : " %s"
format of line 7 : " %s"
format of line 8 : " %s"
SHAR_EOF
# End of shell archive
exit 0
--
For comp.sources.unix stuff, mail to sources at uunet.uu.net.
More information about the Comp.sources.unix
mailing list