home *** CD-ROM | disk | FTP | other *** search
- /* :set tabstops=4 */
- static char *RCSid = "$Header: lplot.c,v 1.1 86/04/20 16:16:46 sysad Exp $";
-
- /*
- * $Log: lplot.c,v $
- * Revision 1.1 86/04/20 16:16:46 sysad
- * Initial distribution version
- *
- *
- */
-
-
- /* LPLOT and QUICKPLOT -- main program.
- * This file handles initialization (mostly argument gathering),
- * calls the plot function to fill the output array, then processes
- * the array and outputs it.
- */
-
- /* It is the intent of the author that this software may be distributed
- * and used freely, without restriction. If you make improvements or
- * enhancements, I would appreciate a copy.
- *
- * Duane H. Hesser Teltone Corporation
- * ....uw-beaver!tikal!sysad
- * ....uw-beaver!tikal!dhh
- */
-
- #include "extern.h"
- #ifdef DEBUG
- #include <stdio.h>
- #endif
-
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- extern void onintr();
- extern int read_stream();
- struct inbuf src;
- int files = 0;
- double atof();
- #ifndef QUICKPLOT
- char *user, *host, *actfile;
- #endif
-
- Name = argv[0];
- ++argv;
- #ifdef DEBUG
- setbuf(stdout,(char *)0);
- #endif
- #ifndef QUICKPLOT
- if(strcmp(Name,"rlplot") == 0)
- {
- ++Rotate;
- }
- #endif
-
-
- Eflag = 1;
- #ifdef QUICKPLOT
- getsize((char *)0); /* get the size of the terminal */
- #else
- user = host = actfile = (char *)0;
- #endif
- while(--argc)
- {
- if(argv[0][0] == '-')
- {
- switch(argv[0][1])
- {
- #ifdef QUICKPLOT
- case 'T': /* size for a specific terminal */
- getsize(argv[1]);
- --argc;
- ++argv;
- break;
- case 'c': /* select plotting character */
- plotchar = *argv[1];
- --argc;
- ++argv;
- break;
- #endif
- case 'r': /* rotate entire plot 90 degrees */
- ++Rotate;
- break;
- case 'W':
- maxcol = atoi(argv[1]);
- --argc;
- ++argv;
- break;
- case 'H':
- maxrow = atoi(argv[1]);
- --argc;
- ++argv;
- break;
- case 'X': /* move the whole plot horizontally */
- #ifdef QUICKPLOT
- Xmargin = atof(argv[1]); /* columns */
- #else
- Xmargin = atof(argv[1]) * XPERINCH; /* inches */
- #endif
- --argc;
- ++argv;
- break;
- case 'Y': /* move the whole plot vertically */
- #ifdef QUICKPLOT
- Ymargin = atof(argv[1]); /* rows */
- #else
- Ymargin = atof(argv[1]) * YPERINCH; /* inches */
- #endif
- --argc;
- ++argv;
- break;
- case 's': /* request x, y, or overall scale factors */
- if(argv[0][2] == '\0')
- Scalfac = atof(argv[1]);
- else if(argv[0][2] == 'x')
- argxfac = atof(argv[1]);
- else if(argv[0][2] == 'y')
- argyfac = atof(argv[1]);
- --argc;
- ++argv;
- break;
- case 'e': /* force erase before each file is plotted */
- ++Eflag;
- Nflag = 0;
- break;
- case 'N': /* suppress erasing */
- ++Nflag;
- Eflag = 0;
- break;
- #ifndef QUICKPLOT
- case 'x': /* get width in pixels (from lpr) */
- maxcol = atoi(&argv[0][2]);
- break;
- case 'y': /* get hieght in pixels (from lpr) */
- maxrow = atoi(&argv[0][2]);
- break;
- case 'n': /* get user (from lpr) for accounting */
- user = argv[1];
- ++argv;
- --argc;
- break;
- case 'h': /* get host and accounting file (from lpr) */
- host = argv[1];
- ++argv; --argc;
- actfile = argv[2];
- --argc; ++argv;
- break;
- #endif
- #ifdef DEBUG
- case 'd': /* debug */
- debug = atoi(argv[1]);
- ++argv;
- --argc;
- break;
- #endif
- case '\0': /* read standard input here */
- src.fd = 0;
- src.nleft = 0;
- src.eof = 0;
- lplot(&src);
- if(Plotdata && Eflag) output();
- bufclose(&src);
- break;
- default:
- break;
- }
- }
- else /* file argument */
- {
- if(bufopen(argv[0],&src) < 0)
- {
- char ebuf[64];
- sprintf(ebuf,"%s: can't open input %s\n",Name,argv[0]);
- write(2,ebuf,strlen(ebuf));
- exit(1);
- }
- lplot(&src);
- if(Plotdata && Eflag) output();
- bufclose(&src);
- files++;
- }
- argv++;
- }
- Nflag = 0;
- if(files == 0) /* no file arguments given; read stdin */
- {
- src.fd = 0;
- src.nleft = 0;
- src.eof = 0;
- lplot(&src);
- }
- if(Plotdata) output(); /* force out anything that may be left */
- #ifndef QUICKPLOT
- if(actfile && *actfile && (access(actfile,02) == 0))
- {
- int fda = open(actfile,1);
- char abuf[32];
- if(fda < 0) exit(0);
- if(!user || !*user) user = "lplot";
- if(!host || !*host) host = "unknown";
- sprintf(abuf,"%7.2f\t%s:%s\n", (float)Npages, host, user);
- write(fda,abuf,strlen(abuf));
- }
- #endif
- exit(0);
- }
-
- lplot(source)
- struct inbuf *source;
- {
- int got;
- /* This next is a hack to suppress an initial "erase" command,
- * (as "graph(1)" is so fond of issuing) before there is anything
- * to plot. If there is plot data, the erase will force it out.
- * After the first page is printed, an erase will be honored
- * unconditionally (unless erasing is suppressed with '-N').
- */
- static int firstplot = 1;
-
- while( (got = read_stream(source)))
- {
- #ifdef DEBUG
- if(debug & 2) printf("got=%ld,Plotdata=%d\n",got,Plotdata);
- #endif
- /* got = -1 means no plot cmds except erase */
- if((got == -1) && !Nflag && !Plotdata)
- {
- if(!firstplot)
- write(1,"\014",1);
- continue;
- }
- Plotdata++; /* there is something to plot */
- firstplot = 0;
- if(!Nflag && got < 0) /* erase command received */
- output();
- }
- }
-
- /* Send the plot data to stdout. The data are processed by rows,
- * each of which is treated as a string. We don't send nulls at
- * the end of the string, but we must fill in null bytes before
- * the last byte in the row which contains data. For lplot, we
- * must set bit 6 ('\100') to make the byte valid for plotting;
- * for quickplot, null bytes need to be spaces.
- */
- output()
- {
- int y,len,maxc;
- char c;
- struct outbuf outbuf;
-
- outbuf.datalen = 0;
- outbuf.nextp = outbuf.buffer;
-
- #ifdef QUICKPLOT
- maxc = maxcol;
- #else
- maxc = (maxcol + 5)/6;
- #endif
- #ifdef DEBUG
- if(debug & 2) printf("output:maxc=%d\n",maxc);
- #endif
-
- for(y = maxrow - 1; y >= 0; --y)
- {
- char *row = Row[y];
- char *end = &row[maxc];
-
- /* make sure the string is terminated */
- *end-- = '\0';
-
- /* find the last non-null byte in the row */
- while(!*end && (end >= row)) end--;
- len = end - row + 1;
- #ifdef DEBUG
- if(debug & 4) printf("row[%d]=%d bytes\n",y,len);
- #endif
-
- #ifndef QUICKPLOT
- /* set bit 6 in all bytes to be transmitted */
- while(end >= row) *end-- |= BIT[6];
- Row[y][len++] = GRAPHICSCHAR;
- Row[y][len++] = '\n';
- Row[y][len] = '\0';
- #else
- /* just send a space for quickplot */
- while(end >= row) if(!*end) *end-- = ' '; else --end;
- len = strlen(Row[y]);
- /* leave cursor lower right */
- if(y)
- {
- strcat(Row[y],"\n");
- ++len;
- }
- #endif
- bufwrite(Row[y],len,&outbuf);
- #ifdef DEBUG
- if(debug & 4) buf_flush(&outbuf);
- #endif
- bzero(Row[y],XARRAYSIZE); /* clear the array for next plot */
- }
- Plotdata = 0;
- buf_flush(&outbuf);
- #ifdef QUICKPLOT
- /* Pause after each plot unless output is redirected.
- * Read from the error channel because we might be reading
- * plot data from stdin.
- */
- if(isatty(1) && isatty(2)) read(2,&c,1);
- else write(1,"\n",1);
- #else
- /* for accounting, one page per plot */
- Npages++;
- #endif
- }
-
- #ifdef QUICKPLOT
- /* get the size of the terminal from the environment */
- getsize(term)
- char *term;
- {
- char *terminal,termbuf[1024],*getenv();
- int cols,lines;
-
- /* set defaults */
- maxcol = cols = XDOTS;
- maxrow = lines = YDOTS;
-
- if(!term) terminal = getenv("TERM");
- else terminal = term;
-
- if((terminal) && (tgetent(termbuf,terminal) == 1))
- {
- cols = tgetnum("co");
- if(cols > 0) maxcol = cols;
- lines = tgetnum("li");
- if(lines > 0) maxrow = lines;
- autowrap = tgetflag("am");
- }
- spacex = maxcol;
- spacey = maxrow;
- }
- #endif QUICKPLOT
-