rsalz@bbn.com (Rich Salz) (02/17/88)
Submitted-by: Joe Chen <joec%wasat.usc.edu@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@wasat.usc.edu, joec@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@wasat.usc.edu, joec@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@wasat.usc.edu, joec@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@wasat.usc.edu, joec@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@wasat.usc.edu, joec@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@uunet.uu.net.