home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / quickplot / part2 / lplot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  7.4 KB  |  347 lines

  1. /* :set tabstops=4                                                    */
  2. static char *RCSid = "$Header: lplot.c,v 1.1 86/04/20 16:16:46 sysad Exp $";
  3.  
  4. /*
  5.  * $Log:    lplot.c,v $
  6.  * Revision 1.1  86/04/20  16:16:46  sysad
  7.  * Initial distribution version
  8.  * 
  9.  * 
  10.  */
  11.  
  12.  
  13. /* LPLOT and QUICKPLOT -- main program.
  14.  * This file handles initialization (mostly argument gathering),
  15.  * calls the plot function to fill the output array, then processes
  16.  * the array and outputs it.
  17.  */
  18.  
  19. /* It is the intent of the author that this software may be distributed
  20.  * and used freely, without restriction.  If you make improvements or
  21.  * enhancements, I would appreciate a copy.
  22.  *
  23.  * Duane H. Hesser    Teltone Corporation
  24.  * ....uw-beaver!tikal!sysad
  25.  * ....uw-beaver!tikal!dhh
  26.  */
  27.  
  28. #include "extern.h"
  29. #ifdef DEBUG
  30. #include <stdio.h>
  31. #endif
  32.  
  33.  
  34. main(argc,argv)
  35. int argc;
  36. char **argv;
  37. {
  38.     extern void onintr();
  39.     extern int read_stream();
  40.     struct inbuf src;
  41.     int files = 0;
  42.     double atof();
  43. #ifndef QUICKPLOT
  44.     char *user, *host, *actfile;
  45. #endif
  46.  
  47.     Name = argv[0];
  48.     ++argv;
  49. #ifdef DEBUG
  50.     setbuf(stdout,(char *)0);
  51. #endif
  52. #ifndef QUICKPLOT
  53.     if(strcmp(Name,"rlplot") == 0)
  54.     {
  55.         ++Rotate;
  56.     }
  57. #endif
  58.  
  59.  
  60.     Eflag = 1;
  61. #ifdef QUICKPLOT
  62.     getsize((char *)0);                /* get the size of the terminal */
  63. #else
  64.     user = host = actfile = (char *)0;
  65. #endif
  66.     while(--argc) 
  67.     {
  68.         if(argv[0][0] == '-')
  69.         {
  70.             switch(argv[0][1])
  71.             {
  72. #ifdef QUICKPLOT
  73.             case 'T':    /* size for a specific terminal                */
  74.                 getsize(argv[1]);
  75.                 --argc;
  76.                 ++argv;
  77.                 break;
  78.             case 'c':    /* select plotting character                */
  79.                 plotchar = *argv[1];
  80.                 --argc;
  81.                 ++argv;
  82.                 break;
  83. #endif
  84.             case 'r':    /* rotate entire plot 90 degrees            */
  85.                 ++Rotate;
  86.                 break;
  87.             case 'W':
  88.                 maxcol = atoi(argv[1]);
  89.                 --argc;
  90.                 ++argv;
  91.                 break;
  92.             case 'H':
  93.                 maxrow = atoi(argv[1]);
  94.                 --argc;
  95.                 ++argv;
  96.                 break;
  97.             case 'X':    /* move the whole plot horizontally            */
  98. #ifdef QUICKPLOT
  99.                 Xmargin = atof(argv[1]);                /* columns    */
  100. #else
  101.                 Xmargin = atof(argv[1]) * XPERINCH;        /* inches    */
  102. #endif
  103.                 --argc;
  104.                 ++argv;
  105.                 break;
  106.             case 'Y':    /* move the whole plot vertically            */
  107. #ifdef QUICKPLOT
  108.                 Ymargin = atof(argv[1]);                /* rows        */
  109. #else
  110.                 Ymargin = atof(argv[1]) * YPERINCH;        /* inches    */
  111. #endif
  112.                 --argc;
  113.                 ++argv;
  114.                 break;
  115.             case 's':    /* request x, y, or overall scale factors    */
  116.                 if(argv[0][2] == '\0')
  117.                     Scalfac = atof(argv[1]);
  118.                 else if(argv[0][2] == 'x')
  119.                     argxfac = atof(argv[1]);
  120.                 else if(argv[0][2] == 'y')
  121.                     argyfac = atof(argv[1]);
  122.                 --argc;
  123.                 ++argv;
  124.                 break;
  125.             case 'e':    /* force erase before each file is plotted    */
  126.                 ++Eflag;
  127.                 Nflag = 0;
  128.                 break;
  129.             case 'N':    /* suppress erasing                            */
  130.                 ++Nflag;
  131.                 Eflag = 0;
  132.                 break;
  133. #ifndef QUICKPLOT
  134.             case 'x':    /* get width in pixels (from lpr)            */
  135.                 maxcol = atoi(&argv[0][2]);
  136.                 break;
  137.             case 'y':    /* get hieght in pixels (from lpr)            */
  138.                 maxrow = atoi(&argv[0][2]);
  139.                 break;
  140.             case 'n':    /* get user (from lpr) for accounting        */
  141.                 user = argv[1];
  142.                 ++argv;
  143.                 --argc;
  144.                 break;
  145.             case 'h':    /* get host and accounting file (from lpr)    */
  146.                 host = argv[1];
  147.                 ++argv; --argc;
  148.                 actfile = argv[2];
  149.                 --argc; ++argv;
  150.                 break;
  151. #endif
  152. #ifdef DEBUG
  153.             case 'd':    /* debug                                    */
  154.                 debug = atoi(argv[1]);
  155.                 ++argv;
  156.                 --argc;
  157.                 break;
  158. #endif
  159.             case '\0':    /* read standard input here                    */
  160.                 src.fd = 0;
  161.                 src.nleft = 0;
  162.                 src.eof = 0;
  163.                 lplot(&src);
  164.                 if(Plotdata && Eflag) output();
  165.                 bufclose(&src);
  166.                 break;
  167.             default:
  168.                 break;
  169.             }
  170.         }
  171.         else        /* file argument                                */
  172.         {
  173.             if(bufopen(argv[0],&src) < 0) 
  174.             {
  175.                 char ebuf[64];
  176.                 sprintf(ebuf,"%s: can't open input %s\n",Name,argv[0]);
  177.                 write(2,ebuf,strlen(ebuf));
  178.                 exit(1);
  179.             }
  180.             lplot(&src);
  181.             if(Plotdata && Eflag) output();
  182.             bufclose(&src);
  183.             files++;
  184.         }
  185.         argv++;
  186.     }
  187.     Nflag = 0;
  188.     if(files == 0)    /* no file arguments given; read stdin            */
  189.     {
  190.         src.fd = 0;
  191.         src.nleft = 0;
  192.         src.eof = 0;
  193.         lplot(&src);
  194.     }
  195.     if(Plotdata) output();    /* force out anything that may be left    */
  196. #ifndef QUICKPLOT
  197.     if(actfile && *actfile && (access(actfile,02) == 0))
  198.     {
  199.         int fda = open(actfile,1);
  200.         char abuf[32];
  201.         if(fda < 0) exit(0);
  202.         if(!user || !*user) user = "lplot";
  203.         if(!host || !*host) host = "unknown";
  204.         sprintf(abuf,"%7.2f\t%s:%s\n", (float)Npages, host, user);
  205.         write(fda,abuf,strlen(abuf));
  206.     }
  207. #endif
  208.     exit(0);
  209. }
  210.  
  211. lplot(source)
  212. struct inbuf *source;
  213. {
  214.     int got;
  215.     /* This next is a hack to suppress an initial "erase" command,
  216.      * (as "graph(1)" is so fond of issuing) before there is anything
  217.      * to plot.  If there is plot data, the erase will force it out.
  218.      * After the first page is printed, an erase will be honored
  219.      * unconditionally (unless erasing is suppressed with '-N').
  220.      */
  221.     static int firstplot = 1;
  222.  
  223.     while( (got = read_stream(source)))
  224.     {
  225. #ifdef DEBUG
  226.         if(debug & 2) printf("got=%ld,Plotdata=%d\n",got,Plotdata);
  227. #endif
  228.         /* got = -1 means no plot cmds except erase                    */
  229.         if((got == -1) && !Nflag && !Plotdata)
  230.         {
  231.             if(!firstplot)
  232.                 write(1,"\014",1);
  233.             continue;
  234.         }
  235.         Plotdata++;                /* there is something to plot        */
  236.         firstplot = 0;
  237.         if(!Nflag && got < 0)    /* erase command received            */
  238.             output();
  239.     }
  240. }
  241.  
  242. /* Send the plot data to stdout.  The data are processed by rows,
  243.  * each of which is treated as a string.  We don't send nulls at
  244.  * the end of the string, but we must fill in null bytes before
  245.  * the last byte in the row which contains data.  For lplot, we
  246.  * must set bit 6 ('\100') to make the byte valid for plotting;
  247.  * for quickplot, null bytes need to be spaces.
  248.  */
  249. output()
  250. {
  251.     int y,len,maxc;
  252.     char c;
  253.     struct outbuf outbuf;
  254.  
  255.     outbuf.datalen = 0;
  256.     outbuf.nextp = outbuf.buffer;
  257.  
  258. #ifdef QUICKPLOT
  259.     maxc = maxcol;
  260. #else
  261.     maxc = (maxcol + 5)/6;
  262. #endif
  263. #ifdef DEBUG
  264.     if(debug & 2) printf("output:maxc=%d\n",maxc);
  265. #endif
  266.  
  267.     for(y = maxrow - 1; y >= 0; --y)
  268.     {
  269.         char *row = Row[y];
  270.         char *end = &row[maxc];
  271.  
  272.         /* make sure the string is terminated                         */
  273.         *end-- = '\0';
  274.  
  275.         /* find the last non-null byte in the row                    */
  276.         while(!*end && (end >= row))    end--;
  277.         len = end - row + 1;
  278. #ifdef DEBUG
  279.         if(debug & 4) printf("row[%d]=%d bytes\n",y,len);
  280. #endif
  281.  
  282. #ifndef QUICKPLOT
  283.         /* set bit 6 in all bytes to be transmitted                    */
  284.         while(end >= row) *end-- |= BIT[6]; 
  285.         Row[y][len++] = GRAPHICSCHAR;
  286.         Row[y][len++] = '\n';
  287.         Row[y][len] = '\0';
  288. #else
  289.         /* just send a space for quickplot                            */
  290.         while(end >= row) if(!*end) *end-- = ' '; else --end;
  291.         len = strlen(Row[y]);
  292.         /* leave cursor lower right                                    */
  293.         if(y)
  294.         {
  295.             strcat(Row[y],"\n");
  296.             ++len;
  297.         }
  298. #endif
  299.         bufwrite(Row[y],len,&outbuf);
  300. #ifdef DEBUG
  301.         if(debug & 4) buf_flush(&outbuf);
  302. #endif
  303.         bzero(Row[y],XARRAYSIZE);    /* clear the array for next plot */
  304.     }
  305.     Plotdata = 0;
  306.     buf_flush(&outbuf);
  307. #ifdef QUICKPLOT
  308.     /* Pause after each plot unless output is redirected.
  309.      * Read from the error channel because we might be reading
  310.      * plot data from stdin.
  311.      */
  312.     if(isatty(1) && isatty(2)) read(2,&c,1);
  313.     else write(1,"\n",1);
  314. #else
  315.     /* for accounting, one page per plot                            */
  316.     Npages++;
  317. #endif
  318. }
  319.  
  320. #ifdef QUICKPLOT
  321. /* get the size of the terminal from the environment                */
  322. getsize(term)
  323. char *term;
  324. {
  325.     char *terminal,termbuf[1024],*getenv();
  326.     int cols,lines;
  327.  
  328.     /* set defaults                                                    */
  329.     maxcol = cols = XDOTS;
  330.     maxrow = lines = YDOTS;
  331.  
  332.     if(!term) terminal = getenv("TERM");
  333.     else terminal = term;
  334.  
  335.     if((terminal)  && (tgetent(termbuf,terminal) == 1))
  336.     {
  337.         cols = tgetnum("co");
  338.         if(cols > 0) maxcol = cols;
  339.         lines = tgetnum("li");
  340.         if(lines > 0) maxrow = lines;
  341.         autowrap = tgetflag("am");
  342.     }
  343.     spacex = maxcol;
  344.     spacey = maxrow;
  345. }
  346. #endif QUICKPLOT
  347.