home *** CD-ROM | disk | FTP | other *** search
- /* -- 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() */
-