home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gle / gle / graph.c < prev    next >
C/C++ Source or Header  |  1992-11-29  |  26KB  |  990 lines

  1. #define GRAPHDEF
  2. #include "graph.h"
  3. int freedataset(int i);
  4. int free_temp(void);
  5. int set_sizelength(void);
  6. extern int trace_on;
  7. extern int this_line;
  8. static int xxgrid[5];
  9.     double koffsetx=0,koffsety=0,khei=0;    /* key variables */
  10.     char kpos[30];
  11.     int knobox=0;                /* end key vraibles */
  12.     char *letstr[20];
  13.     int nlet;
  14. int draw_graph(void);
  15. begin_graph(int *pln,long *pcode, int *cp)
  16. {
  17.     static int ct,i,ncol,ntmp,np,*m,t,d;
  18.     static int iid1,iid2,d2,st;
  19.     double *px,*py,ox,oy;
  20.     static int xset,erflg,gosret;
  21.     FILE *fptr;
  22.  
  23.     nlet = 0;
  24.     koffsetx=0; koffsety=0; khei=0;    /* key variables */
  25.     kpos[0] = 0;
  26.     knobox=0;                /* end key vraibles */
  27.     freeafont();  /* get some more memory, we might need it */
  28.     g_hscale = .7;
  29.     g_vscale = .7;
  30.  
  31.     nlet = 0;
  32.     erflg = true;
  33.     for (i=1;i<5;i++) { xxgrid[i] = 0; vinit_axis(i);}
  34.     graph_init();
  35.     /* ! set up some more constants (defaults)*/
  36.     g_get_usersize(&g_xsize,&g_ysize);
  37.     set_sizelength();
  38.  
  39.     dp[0] = myallocz(sizeof(*dp[1]));  /* dataset for default settings */
  40.    dp[0]->lwidth = -1;
  41.     begin_init();
  42.     this_line -= 2;
  43.     for (;;) {
  44.  
  45.     srclin[0] = 0;
  46.     st = begin_token(&pcode,cp,pln,srclin,(char *) tk,&ntk,outbuff);
  47.     if (trace_on) gprint("Graph   | %s %d \n",srclin,st);
  48.     if (trace_on) {
  49.         for (i=1;i<=ntk;i++) gprint("{%s} ",tk[i]);
  50.         gprint("\n");
  51.     }
  52.     this_line++;
  53.     if (!st) {draw_graph(); return;}
  54.     ct = 1;
  55.     while (ct<=ntk)  {
  56.     if (strcmp(tk[ct],"BAR")==0)  goto do_bar;
  57.     if (strcmp(tk[ct],"DATA")==0)  goto do_data;
  58.     kw("DATA")     goto do_data;
  59.     kw("EXTRACT")     goto do_extract;
  60.     kw("FILL")     goto do_fill;
  61.     kw("HSCALE")     goto do_hscale;
  62.     kw("LET")     goto do_letsave;
  63.     kw("NOBOX")     goto do_nobox;
  64.     kw("NOBORDER")     goto do_nobox;
  65.     kw("SIZE")     goto do_size;
  66.     kw("KEY")     goto do_key;
  67.     kw("VSCALE")     goto do_vscale;
  68.     kw("FULLSIZE")     goto do_fullsize;
  69.     kw("TITLE")     goto do_main_title;
  70.     kw("!")     goto do_next_line;
  71.     xset = 0;
  72.     if (strstr(tk[ct],"AXIS")!=NULL)           xset = 1;
  73.     else if (strstr(tk[ct],"LABELS")!=NULL)     xset = 2;
  74.     else if (strstr(tk[ct],"SIDE")!=NULL)         xset = 3;
  75.     else if (strstr(tk[ct],"SUBTICKS")!=NULL)     xset = 5;
  76.     else if (strstr(tk[ct],"TICKS")!=NULL)         xset = 4;
  77.     if (xset>0) goto do_axisset;
  78.     if (strstr(tk[ct],"NAMES")!=NULL)         goto do_names;
  79.     if (strstr(tk[ct],"PLACES")!=NULL)         goto do_places;
  80.     if (strstr(tk[ct],"TITLE")!=NULL)         goto do_title;
  81.     if (*tk[ct]=='D')                 goto do_datasets;
  82.     gprint("Unrecognised graph sub command {%s} %d \n ",tk[ct],ct);
  83.     goto do_next_line;
  84. do_next_token:;
  85.     }
  86. do_next_line:
  87.     erflg = true;
  88.     if (!begin_next_line(pcode,cp)) {draw_graph(); return;}
  89.     }
  90.  
  91. /* ----------------------------------------------------------------*/
  92. /* this disgusting piece of code is due to no     gosub/return   */
  93. /* (a few months later)... and my own ignorance of C */
  94. do_axisset:
  95.     t = axis_type(tk[1]);
  96.     erflg = true;
  97.     gosret = 1;
  98.     switch (xset) {
  99.       case 1:
  100.         gosret = 2;
  101.         goto do_axis;
  102. doax2:
  103.         erflg = false;
  104.         goto do_labels;
  105. doax3:
  106.         goto do_side;
  107. doax4:
  108.     goto do_ticks;
  109.       case 2:
  110.         goto do_labels;
  111.       case 3:
  112.         goto do_side;
  113.       case 4:
  114.         goto do_ticks;
  115.       case 5:
  116.         goto do_subticks;
  117.     }
  118. end_axisset:
  119.     if (t>2) goto do_next_line;
  120.     erflg = false;
  121.     t = t + 2;
  122.     erflg = false;
  123.     gosret = 0;
  124.     switch (xset) {
  125.       case 1:
  126.         gosret = 3;
  127.         goto do_axis;
  128. doax5:        goto do_labels;
  129. doax6:        goto do_side;
  130. doax7:        goto do_ticks;
  131.       case 2:
  132.         goto do_labels;
  133.       case 3:
  134.         goto do_side;
  135.       case 4:
  136.         goto do_ticks;
  137.       case 5:
  138.         goto do_subticks;
  139.     }
  140. goto do_next_line;
  141. /* ----------------------------------------------------------------*/
  142. do_bar:
  143.     /* bar d1,d2,d3 from d4,d5,d6 color red,green,blue fill grey,blue,green
  144.         dist exp, width exp, LSTYLE 3,445,1
  145.         3dbar .5 .5 top black,black,black side red,green,blue  notop */
  146. {
  147.     int ng,fi,di;
  148.     char *ss;
  149.     g_nbar++;
  150.     br[g_nbar] = myallocz(sizeof(*br[1]));
  151.     br[g_nbar]->ngrp = 0;
  152.     ct = 2;
  153.     ss = strtok(tk[ct],",");
  154.     while (ss!=NULL) {
  155.       if (*ss=='D') {
  156.         ng = (br[g_nbar]->ngrp)++;
  157.         d =  atoi(ss+1);
  158.         if (d==0 || d>99) gprint("Error in bar command {%s}  token number %d \n",tk[ct],ct);
  159.         br[g_nbar]->to[ng] = d;
  160.        }
  161.       ss = strtok(0,",");
  162.     }
  163.  
  164.     for (i=1;i<=ng;i++) {
  165.         br[g_nbar]->color[i] = g_get_grey(0.0);
  166.         br[g_nbar]->fill[i] = g_get_grey(1.0-ng/(i));
  167.         br[g_nbar]->from[i] = 0;
  168.         g_get_line_width(&br[g_nbar]->lwidth[i]);
  169.         strcpy(br[g_nbar]->lstyle[i] ,"1\0");
  170.     }
  171.  
  172.     ct++;
  173.     while (ct<=ntk)  {
  174.         kw("DIST")     br[g_nbar]->dist = next_exp;
  175.        else kw("WIDTH")     br[g_nbar]->width = next_exp;
  176.        else kw("3D") {
  177.         br[g_nbar]->x3d = next_exp;
  178.         br[g_nbar]->y3d = next_exp;
  179.        }
  180.        else kw("NOTOP")     br[g_nbar]->notop = true;
  181.        else kw("LSTYLE")     next_str((char *) br[g_nbar]->lstyle);
  182.        else kw("FROM") {
  183.         fi = 0;
  184.         ct +=1;
  185.         ss = strtok(tk[ct],",");
  186.         while (ss!=NULL) {
  187.           if (*ss=='D') {
  188.             di =  atoi(ss+1);
  189.             br[g_nbar]->from[fi++] = di;
  190.           }
  191.           ss = strtok(0,",");
  192.         }
  193.        }
  194.        else kw("COLOR") {
  195.         fi = 0;ct += 1;
  196.         ss = strtok(tk[ct],",");
  197.         while (ss!=NULL) {
  198.           br[g_nbar]->color[fi++] = pass_color(ss);
  199.           ss = strtok(0,",");
  200.         }
  201.        }
  202.        else kw("SIDE") {
  203.         fi = 0;ct += 1;
  204.         ss = strtok(tk[ct],",");
  205.         while (ss!=NULL) {
  206.           br[g_nbar]->side[fi++] = pass_color(ss);
  207.           ss = strtok(0,",");
  208.         }
  209.        }
  210.        else kw("TOP") {
  211.         fi = 0;ct += 1;
  212.         ss = strtok(tk[ct],",");
  213.         while (ss!=NULL) {
  214.           br[g_nbar]->top[fi++] = pass_color(ss);
  215.           ss = strtok(0,",");
  216.         }
  217.        }
  218.        else kw("FILL") {
  219.         fi = 0; ct++;
  220.         ss = strtok(tk[ct],",");
  221.         while (ss!=NULL) {
  222.           br[g_nbar]->fill[fi++] = pass_color(ss);
  223.           ss = strtok(0,",");
  224.         }
  225.        }
  226.        else gprint("Unrecognised GRAPH BAR sub command {%s} %d \n "
  227.         ,tk[ct],ct);
  228.       ct++;
  229.     }
  230. }
  231. goto do_next_line;
  232. /*----------------------------------------------------------------*/
  233. /* fill x1,d2 color green xmin 1 xmax 2 ymin 1 ymax 2   */
  234. /* fill d1,x2 color green xmin 1 xmax 2 ymin 1 ymax 2   */
  235. /* fill d1,d2 color green xmin 1 xmax 2 ymin 1 ymax 2   */
  236. /* fill d1 color green xmin 1 xmax 2 ymin 1 ymax 2      */
  237. do_fill:
  238. {
  239.     char *ss,s1[40],s2[40];
  240.     fd[++nfd] = myallocz(sizeof(*fd[1]));
  241.     ct = 2;
  242.     strcpy(s1,strtok(tk[ct],","));
  243.     ss = strtok(0,",");
  244.     if (ss==NULL) strcpy(s2,""); else {
  245.         strcpy(s2,ss);
  246.         strtok(0,",");
  247.     }
  248.  
  249.     if (strcmp(s1,"X1")==0) {
  250.         fd[nfd]->type = 1;
  251.         d = atoi(s2+1);
  252.         if (d==0) { gprint("Not a valid fill option {%s} wanted FILL X1,D1 \n",tk[ct]); goto end_fill_read; }
  253.         fd[nfd]->da = d;
  254.     } else if (strcmp(s2,"X2")==0) {
  255.         fd[nfd]->type = 2;
  256.         d = atoi(s1+1);
  257.         if (d==0) { gprint("Not a valid fill option {%s} wanted FILL D2,X2 \n",tk[ct]); goto end_fill_read; }
  258.         fd[nfd]->da = d;
  259.     } else if (strcmp(s2,"")!=0) {
  260.         fd[nfd]->type = 3;
  261.         d = atoi(s1+1);
  262.         d2 = atoi(s2+1);
  263.         if (d==0 || d2==0) { gprint("Expecting FILL D1,D2  found {%s}\n",tk[ct]); goto end_fill_read; }
  264.         fd[nfd]->da = d;
  265.         fd[nfd]->db = d2;
  266.     } else if (*s1=='D') {
  267.         fd[nfd]->type = 4;
  268.         d = atoi(s1+1);
  269.         if (d==0) { gprint("Expecting FILL d1 found {%s} \n",tk[ct]); goto end_fill_read; }
  270.         fd[nfd]->da = d;
  271.     } else {
  272.         gprint("Invalid fill option, wanted d1,d2 or x1,d1 or d1,x2 or d1 \n");
  273.         goto end_fill_read;
  274.     }
  275.     ct++;
  276.  
  277.     fd[nfd]->color = g_get_grey(1.0-nfd*.1);
  278.     fd[nfd]->xmin = -LARGE_NUM;
  279.     fd[nfd]->xmax = LARGE_NUM;
  280.     fd[nfd]->ymin = -LARGE_NUM;
  281.     fd[nfd]->ymax = LARGE_NUM;
  282.  
  283.     while (ct<=ntk)  {
  284.         kw("COLOR")     {ct++; fd[nfd]->color = pass_color(tk[ct]);}
  285.        else kw("XMIN")     fd[nfd]->xmin = next_exp;
  286.        else kw("XMAX")     fd[nfd]->xmax = next_exp;
  287.        else kw("YMIN")     fd[nfd]->ymin = next_exp;
  288.        else kw("YMAX")     fd[nfd]->ymax = next_exp;
  289.        else gprint("Unrecognised GRAPH FILL sub command {%s} %d (Note: CGLE syntax change\n  Expected COLOR,XMIN,XMAX,YMIN,YMAX \n "
  290.         ,tk[ct],ct);
  291.        ct++;
  292.     }
  293. }
  294. end_fill_read:;
  295. goto do_next_line;
  296. /*----------------------------------------------------------------*/
  297. do_key:
  298.     ct = 2;
  299.     while (ct<=ntk)  {
  300.         kw("POS")     next_str(kpos);
  301.        else kw("POSITION")     next_str(kpos);
  302.        else kw("HEI")     khei = next_exp;
  303.        else kw("NOBOX")     knobox = true;
  304.        else kw("OFFSET")     {koffsetx = next_exp;koffsety = next_exp;}
  305.        else gprint("Unrecognised GRAPH KEY sub command {%s} %d \nExpected  KEY POS BL,TL,BR,TR HEI .6 NOBOX OFFSET 2 3 \n"
  306.         ,tk[ct],ct);
  307.        ct++;
  308.     }
  309. goto do_next_line;
  310. /*----------------------------------------------------------------*/
  311. /* data a.dat                */
  312. /* data a.dat d2 d5            */
  313. /* data a.dat d1=c1,c3  d2=c5,c1    */
  314. do_data:
  315. {
  316.     static char data_d[60],data_x[60],data_y[60];
  317.     int nm=0,expect_col=0,extract=0,xi,yi,dn,j,nncol=0,allind;
  318.     char *s1,buff1[30];
  319.     char infile[80];
  320.     ntmp = 0;
  321.     allind = 0;
  322.     for (i=1;i<59;i++) {    /* default mapping if no dataset names given */
  323.         data_d[i] = freedataset(i);
  324.         data_x[i] = 1;
  325.         data_y[i] = i+1;
  326.     }
  327.     while (ct<=ntk)  { if (strstr(tk[ct],"=")!=NULL) extract = true; ct++; }
  328.     ct = 3;
  329.     if (extract==true) {
  330.      while (ct<=ntk)  {
  331.         if (*tk[ct]=='D') {
  332.             nm++;
  333.             strncpy(buff1,tk[ct],29);
  334.             s1 = strtok(buff1,"=");
  335.             if (s1!=NULL) data_d[nm] = atoi(s1+1);
  336.             if (s1==NULL || data_d[nm]==0) gprint("Expecting Dn=Ca,Cb (no spaces) {%s}\n",tk[ct]);
  337.             s1 = strtok(NULL,",");
  338.             if (s1!=NULL) data_x[nm] = atoi(s1+1);
  339.             s1 = strtok(NULL,",");
  340.             if (*s1=='*') {
  341.                 allind = data_d[nm];
  342.             } else {
  343.              if (s1!=NULL) data_y[nm] = atoi(s1+1);
  344.              if (s1==NULL || data_x[nm]==0 || data_y[nm]==0) {
  345.                 gprint("Expecting Dn=Ca,Cb   (no spaces) {%s}\n",tk[ct]);
  346.                 goto do_next_line;
  347.              }
  348.              if (data_x[nm]>expect_col) expect_col = data_x[nm];
  349.              if (data_y[nm]>expect_col) expect_col = data_y[nm];
  350.              }
  351.         } else {
  352.             if (*tk[ct] != 0) gprint("Expecting Dn=Ca,Cb   (no spaces) {%s}\n",tk[ct]);
  353.         }
  354.            ct++;
  355.      }
  356.     } else {
  357.      while (ct<=ntk)  {
  358.         if (*tk[ct]==' ') ct++;
  359.         if (*tk[ct]=='D') {
  360.             nm++;
  361.             data_d[nm] = atoi(tk[ct]+1);
  362.             data_x[nm] = 1;
  363.             data_y[nm] = nm+1;
  364.         } else gprint("Warning, found {%s}, expecting   data a.dat d1 d2 d3 \n",tk[ct]);
  365.            ct++;
  366.       }
  367.     }
  368.     if (expect_col==0 && nm>0) expect_col = nm+1;
  369.     if (allind>0) expect_col = 0;
  370.  
  371. /*
  372.     dbg for (i=1;i<5;i++) {
  373.         gprint("MAPPING %d =  %d %d %d\n",i,data_d[i],data_x[i],data_y[i] );
  374.     }
  375. */
  376.     ct = 2;
  377.     strcpy(infile,tk[2]);
  378.     if (strchr(infile,'$')!=NULL) {
  379.         { int idx,typ;
  380.         var_find(infile,&idx,&typ) ;
  381.         if (idx>=0) var_getstr(idx,infile);
  382.     }}
  383.     strlwr(infile);
  384.     fptr = fopen(infile,"r");
  385.     if (fptr==NULL) {
  386.         gprint("Unable to open data file {%s} \n",infile);
  387.         perror("Reason");
  388.         goto do_next_line;
  389.     }
  390.     for (;!(feof(fptr));) {
  391. /*         if (*tk[ct]==' ') ct++; */
  392.         inbuff[0]=0;
  393.         fgets(inbuff,200,fptr);
  394.         if (inbuff[0]=='"') continue;
  395.         alloc_temp(ntmp);
  396.         if (tmpf == NULL) {
  397.           gprint("Too many points in {%s}, reduce points, split file or use VAX CGLE \n",infile);
  398.           break;
  399.         }
  400.         token_data(inbuff,tk,&ntk,tkbuff);
  401.         ncol = 0;
  402.         for (i=1;i<=ntk;i++) {
  403.             ncol++;
  404.             if (strcmp(tk[i],"*")==0)   {
  405.                 tmpmiss[++ntmp] = true;
  406.             }
  407.             else if (strcmp(tk[i],"-")==0) {
  408.                   tmpmiss[++ntmp] = true;
  409.             }
  410.             else if (strcmp(tk[i],".")==0) {
  411.                   tmpmiss[++ntmp] = true;
  412.             }
  413.             else {
  414.                 tmpf[++ntmp] = atof(tk[i]);
  415.                 tmpmiss[ntmp] = false;
  416.             }
  417.         }
  418.         if (nncol == 0) nncol = ncol;
  419.         if (ncol != nncol) if (ncol>0) {
  420.             if (allind==0) gprint("MUST FIX *** Inconsistent columns in {%s} %d %d \n",infile,ncol,nncol);
  421.         }
  422.         if (nm==0 && ncol>1) nm = ncol-1;
  423.     }
  424.     fclose(fptr);
  425.     if (expect_col>0) if (expect_col>nncol) {
  426.         gprint("Warning, expecting %d columns in data file {%s} found %d \n"
  427.             ,expect_col,infile,ncol);
  428.     }
  429.     if (nncol>0) np = ntmp/nncol;
  430.     if (allind>0) { /* if data file contains y values only, y1, y2 ,y3...*/
  431.         dn = allind;
  432.         np = ntmp;
  433.         if (dn>ndata) ndata = dn;
  434.         if (dp[dn]==NULL) {
  435.             dp[dn] = myallocz(sizeof(*dp[dn]));
  436.             copy_default(dn);
  437.         }
  438.         np++;
  439.         dp[dn]->xv = myallocz(sizeof(*px)*np);
  440.         dp[dn]->yv = myallocz(sizeof(*px)*np);
  441.         dp[dn]->miss = myallocz(sizeof(*m)*np);
  442.         np--;
  443.         px = dp[dn]->xv;
  444.         py = dp[dn]->yv;
  445.         m = dp[dn]->miss;
  446.  
  447.          for (i=1;i<=np;i++) {
  448.             *(px++) = i;
  449.             *(py++) = tmpf[i];
  450.             *(m++) = tmpmiss[i];
  451.             setrange(*(px-1),*(py-1),*(m-1));
  452.         }
  453.         dp[dn]->np = np;
  454.         goto do_next_line;
  455.     }
  456.     for (j=1;j<=nm;j++) {
  457.         dn = data_d[j];
  458.         xi = data_x[j];
  459.         yi = data_y[j];
  460.         if (dn>ndata) ndata = dn;
  461.         if (dp[dn]==NULL) {
  462.             dp[dn] = myallocz(sizeof(*dp[dn]));
  463.             if (dp[dn]==NULL) gprint("Memory allocation error, graph dataset \n");
  464.             copy_default(dn);
  465.         }
  466.         np++;
  467.         dp[dn]->xv = myallocz(sizeof(*px)*np);
  468.         dp[dn]->yv = myallocz(sizeof(*px)*np);
  469.         dp[dn]->miss = myallocz(sizeof(*m)*np);
  470.         np--;
  471.         px = dp[dn]->xv;
  472.         py = dp[dn]->yv;
  473.         m = dp[dn]->miss;
  474.  
  475.          for (i=1;i<=np;i++) {
  476.             *(px++) = tmpf[i*nncol-nncol+xi];
  477.             *(py++) = tmpf[i*nncol-nncol+yi];
  478.             *(m++) = (tmpmiss[i*nncol-nncol+xi]==true)
  479.                 || (tmpmiss[i*nncol-nncol+yi]==true);
  480.             setrange(*(px-1),*(py-1),*(m-1));
  481.             dbg gprint("(xym    %f %f %d \n",*(px-1),*(py-1),*(m-1));
  482.         }
  483.         dp[dn]->np = np;
  484.     }
  485. }
  486. goto do_next_line;
  487. /*----------------------------------------------------------------*/
  488. do_extract:
  489.  
  490. goto do_next_line;
  491. /*----------------------------------------------------------------*/
  492. do_hscale:
  493.     g_hscale = next_exp;
  494. goto do_next_line;
  495. /*----------------------------------------------------------------*/
  496. do_letsave:
  497.     letstr[++nlet] = myalloc(strlen(srclin)+1);
  498.     strcpy(letstr[nlet],srclin);
  499. goto do_next_line;
  500. /*----------------------------------------------------------------*/
  501. do_nobox:
  502.     g_nobox = true;
  503. goto do_next_line;
  504. /*----------------------------------------------------------------*/
  505. do_size:
  506.     g_xsize = next_exp;
  507.     g_ysize = next_exp;
  508.     /* ! set up some more constants */
  509.     set_sizelength();
  510. goto do_next_line;
  511. /*----------------------------------------------------------------*/
  512. do_vscale:
  513.     g_vscale = next_exp;
  514. goto do_next_line;
  515. /*----------------------------------------------------------------*/
  516. do_fullsize:
  517.     g_vscale = 1;
  518.     g_hscale = 1;
  519.     g_nobox = true;
  520. goto do_next_line;
  521. /*----------------------------------------------------------------*/
  522. do_axis:
  523.     ct = 2;
  524. /*     t = axis_type(tk[1]); */
  525.     while (ct<=ntk)  {
  526.         kw("BASE") xx[t].base = next_exp;
  527.         else kw("COLOR") xx[t].color = next_exp;
  528.        else kw("DSUBTICKS") xx[t].dsubticks = next_exp;
  529.        else kw("DTICKS") xx[t].dticks = next_exp;
  530.        else kw("DPOINTS") xx[t].decimal = next_exp;
  531.        else kw("SHIFT") xx[t].shift = next_exp;
  532.        else kw("GRID") xxgrid[t] = true;
  533.        else kw("FONT") xx[t].label_font = next_font;
  534.        else kw("LOG") xx[t].log = true;
  535.        else kw("LSTYLE")     next_str(xx[t].side_lstyle);
  536.        else kw("LWIDTH")     xx[t].side_lwidth = next_exp;
  537.        else kw("MIN") {
  538.         xx[t].min = next_exp;
  539.         xx[t].minset = true;
  540.        }
  541.        else kw("MAX") {
  542.         xx[t].max = next_exp;
  543.         xx[t].maxset = true;
  544.        }
  545.        else kw("HEI")     xx[t].label_hei = next_exp;
  546.        else kw("NOLAST")     xx[t].nolast = true;
  547.        else kw("LAST")     xx[t].nolast = false;
  548.        else kw("FIRST")     xx[t].nofirst = false;
  549.        else kw("NOFIRST")     xx[t].nofirst = true;
  550.        else kw("NSUBTICKS") xx[t].nsubticks = next_exp;
  551.        else kw("NTICKS")     xx[t].nticks = next_exp;
  552.        else kw("ON")     xx[t].off = false;
  553.        else kw("OFF")     xx[t].off = true;
  554.        else gprint("Unrecognised GRAPH %%AXIS sub command {%s} %d\n",tk[ct],ct);
  555.        ct++;
  556.     }
  557.  
  558. if (gosret==2) goto doax2;    /* in axis     */
  559. if (gosret==3) goto doax5;    /* in axis     */
  560. if (gosret==1) goto end_axisset;  /* in axis,label,side,tick,subtick */
  561. goto do_next_line;
  562. /*----------------------------------------------------------------*/
  563. do_names:
  564.     t = axis_type(tk[1]);
  565.     ct = 1;
  566.     while (ct<ntk)  {
  567.         next_quote(strbuf);
  568.         i = ++xx[t].nnam;
  569.         xx[t].names[i] = myallocz(strlen(strbuf)+1);
  570.         strcpy(xx[t].names[i],strbuf);
  571.     }
  572.  
  573. goto do_next_line;
  574. /*----------------------------------------------------------------*/
  575. do_places:    /* x2places, or xplaces, or yplaces or y2places */
  576.     t = axis_type(tk[1]);
  577.     ct = 1;
  578.     while (ct<ntk)  {
  579.         xx[t].places[++xx[t].nplaces] = next_exp;
  580.     }
  581. goto do_next_line;
  582. /*----------------------------------------------------------------*/
  583. do_main_title:
  584.     /* should change position and size of main title */
  585.     t = 3;
  586.     xx[t].title = myallocz(40);
  587.     ct = 1;
  588.     next_vquote(xx[t].title);
  589.     ct = 3;
  590.     xx[t].title_dist = g_fontsz*.7;
  591.     xx[t].title_hei = g_fontsz*1.5;
  592.     while (ct<=ntk)  {
  593.              kw("HEI")     xx[t].title_hei = next_exp;
  594.         else kw("OFF")     xx[t].title_off = true;
  595.         else kw("COLOR")   xx[t].title_color = next_color;
  596.         else kw("FONT")    xx[t].title_font = next_font;
  597.         else kw("DIST")    xx[t].title_dist = next_exp;
  598.         else gprint("Expecting TITLE sub command, found {%s} pos %d\n",tk[ct],ct);
  599.         ct++;
  600.     }
  601. goto do_next_line;
  602. /*----------------------------------------------------------------*/
  603. do_title:
  604.     t = axis_type(tk[1]);
  605.     ct = 1;
  606.     next_vquote(xx[t].title);
  607.     ct = 3;
  608.     while (ct<=ntk)  {
  609.              kw("HEI")     xx[t].title_hei = next_exp;
  610.         else kw("OFF")     xx[t].title_off = true;
  611.         else kw("ROT")     xx[t].title_rot = true;
  612.         else kw("ROTATE")     xx[t].title_rot = true;
  613.         else kw("COLOR")   xx[t].title_color = next_color;
  614.         else kw("FONT")    xx[t].title_font = next_font;
  615.         else kw("DIST")    xx[t].title_dist = next_exp;
  616.         else gprint("Expecting axis TITLE sub command, found {%s} pos %d\n",tk[ct],ct);
  617.         ct++;
  618.     }
  619. goto do_next_line;
  620. /*----------------------------------------------------------------*/
  621. do_labels:
  622.     ct = 2;
  623. /*     t = axis_type(tk[1]); */
  624.     while (ct<=ntk)  {
  625.         if (*tk[ct]==' ') ct++;
  626.              kw("HEI")     xx[t].label_hei = next_exp;
  627.         else kw("OFF")     xx[t].label_off = true;
  628.         else kw("ON")     xx[t].label_off = false;
  629.         else kw("COLOR")   xx[t].label_color = next_color;
  630.         else kw("FONT")    xx[t].label_font = next_font;
  631.         else kw("DIST")    xx[t].label_dist = next_exp;
  632.         else ifer gprint("Expecting LABELS sub command, found {%s} pos %d \n",tk[ct],ct);
  633.         ct++;
  634.     }
  635. if (gosret==2) goto doax3;    /* in label     */
  636. if (gosret==3) goto doax6;    /* in label     */
  637. if (gosret==1) goto end_axisset;  /* in axis,label,side,tick,subtick */
  638. goto do_next_line;
  639. /*----------------------------------------------------------------*/
  640. do_side:
  641.     ct = 2;
  642. /*     t = axis_type(tk[1]); */
  643.     while (ct<=ntk)  {
  644.          if (*tk[ct]==' ') ct++;
  645.              kw("OFF")     xx[t].side_off = true;
  646.         else kw("ON")   xx[t].side_off = false;
  647.         else kw("COLOR")   xx[t].side_color = next_color;
  648.         else kw("LWIDTH")  xx[t].side_lwidth = next_exp;
  649.         else kw("LSTYLE")  next_str(xx[t].side_lstyle);
  650.         else ifer gprint("Expecting SIDE sub command, found {%s} pos %d \n",tk[ct],ct);
  651.         ct++;
  652.     }
  653. if (gosret==2) goto doax4;    /* in side      */
  654. if (gosret==3) goto doax7;    /* in side      */
  655. if (gosret==1) goto end_axisset;  /* in axis,label,side,tick,subtick */
  656. goto do_next_line;
  657. /*----------------------------------------------------------------*/
  658. do_ticks:
  659.     ct = 2;
  660. /*     t = axis_type(tk[1]); */
  661.     while (ct<=ntk)  {
  662.         if (*tk[ct]==' ') ct++;
  663.              kw("LENGTH")  xx[t].ticks_length = next_exp;
  664.         else kw("OFF")     {xx[t].ticks_off = true;
  665.                 xx[t].subticks_off = true;}
  666.         else kw("ON")     {xx[t].ticks_off = false;
  667.                 xx[t].subticks_off = false;}
  668.         else kw("COLOR")   {xx[t].ticks_color = next_color;
  669.                 xx[t].subticks_color = xx[t].ticks_color;}
  670.         else kw("LWIDTH")  xx[t].ticks_lwidth = next_exp;
  671.         else kw("LSTYLE")  next_str(xx[t].ticks_lstyle);
  672.         else ifer gprint("Expecting TICKS sub command, found {%s} pos %d \n",tk[ct],ct);
  673.         ct++;
  674.     }
  675. if (gosret==1 || gosret==2) goto end_axisset; /* in axis,label,side,tick,subtick */
  676. goto do_next_line;
  677. /*----------------------------------------------------------------*/
  678. do_subticks:
  679.     ct = 2;
  680. /*     t = axis_type(tk[1]); */
  681.     while (ct<=ntk)  {
  682.         if (*tk[ct]==' ') ct++;
  683.              kw("LENGTH")     xx[t].subticks_length = next_exp;
  684.         else kw("OFF")       xx[t].subticks_off = true;
  685.         else kw("ON")       xx[t].subticks_off = false;
  686.         else kw("COLOR")       xx[t].subticks_color = next_color;
  687.         else kw("LWIDTH")      xx[t].subticks_lwidth = next_exp;
  688.         else kw("LSTYLE")      next_str(xx[t].subticks_lstyle);
  689.         else ifer gprint("Expecting SUBTICKS sub command, found {%s} pos %d \n",tk[ct],ct);
  690.         ct++;
  691.     }
  692. if (gosret==1 || gosret==2) goto end_axisset; /* in axis,label,side,tick,subtick */
  693. goto do_next_line;
  694. /* ----------------------------------------------------------------*/
  695. do_datasets:
  696.     d = atoi(tk[1]+1); /* dataset number (right$(k$,2))  (0=dn) */
  697.     iid1 = d;
  698.     iid2 = d;
  699.     if (d==0) iid2 = 100;
  700.     if (d!=0) if (dp[d]==NULL) {
  701.         dp[d] = myallocz(sizeof(*dp[ndata]));
  702.         if (dp[d]==NULL) gprint("Memory allocation error, graph dataset \n");
  703.         copy_default(d);
  704.         if (ndata<d) ndata=d;
  705.     }
  706.     for (d=iid1;d<=iid2;d++) {
  707.         if (dp[d]!=NULL) do_dataset(d);
  708.     iid1=iid1;
  709.     }
  710. goto do_next_line;
  711. /*------------------------------------------------------------------*/
  712. /******            Mmmmm !!                 *****/
  713. /*------------------------------------------------------------------*/
  714. }
  715. int zzzz(char *s);
  716. zzzz(char *s)
  717. {
  718. /*    double zz;
  719. /*
  720. /*    g_get_line_width(&zz);
  721.   */
  722.     dbg gprint("graph module %s done line %d \n",s,done_line);
  723.  
  724. }
  725. draw_graph()
  726. {
  727.     int i,freedata=false;
  728.     double ox,oy;
  729.     done_line = false;
  730.     /* ! Ok we've decoded the commands. now draw the thing. */
  731.     if (g_xsize*g_ysize==0) {
  732.         g_xsize = 10; g_ysize = 10;
  733.         g_get_usersize(&g_xsize,&g_ysize);
  734.     }
  735.  
  736.     zzzz("begin");
  737.     /* do LETS now */
  738.     for (i=1;i<=nlet;i++) {
  739.         do_let(letstr[i]);
  740.     }
  741.     preview_big();
  742.     /* do_smooth();  dealt with by draw_line()  */
  743.     window_set();
  744.     /* gosub scale_data scale if xmin, ymin xmax ymax for each dataset.*/
  745.  
  746.  
  747.     g_get_xy(&ox,&oy);    /* get the origin x,y */
  748.     g_gsave();
  749.     g_get_hei(&g_fontsz);
  750.  
  751.     set_sizelength();
  752.  
  753.     zzzz("step1 ");
  754.     for (i=1;i<=2;i++) {
  755.         if (xxgrid[i]) {
  756.             if (i == 1) {
  757.                 xx[i].ticks_length = ylength;
  758.                 xx[i+2].ticks_length = 0.0000001;
  759.                 xx[i].subticks_off = true;
  760.                 xx[i+2].subticks_off = true;
  761.                 xx[i].subticks_length = ylength;
  762.                 xx[i+2].subticks_length = 0.0000001;
  763.             }
  764.             if (i==2) {
  765.                 xx[i].ticks_length = xlength;
  766.                 xx[i+2].ticks_length = 0.0000001;
  767.                 xx[i].subticks_length = xlength;
  768.                 xx[i].subticks_off = true;
  769.                 xx[i+2].subticks_off = true;
  770.                 xx[i+2].subticks_length = 0.0000001;
  771.             }
  772.         }
  773.     }
  774.  
  775.     if (xlength<ylength) g_fontsz = xlength/23;
  776.     g_set_hei(g_fontsz);
  777.  
  778. /*     draw the box */
  779.  
  780.     if (!g_nobox) {
  781.         g_line(ox+g_xsize,oy);
  782.         g_line(ox+g_xsize,oy+g_ysize);
  783.         g_line(ox,oy+g_ysize);
  784.         g_line(ox,oy);
  785.     }
  786.  
  787.     /* set graph globals */
  788.     graph_x1 = xbl;
  789.     graph_y1 = ybl;
  790.     graph_x2 = xbl + xlength;
  791.     graph_y2 = ybl + ylength;
  792.     graph_xmin = wxmin;
  793.     graph_xmax = wxmax;
  794.     graph_ymin = wymin;
  795.     graph_ymax = wymax;
  796.  
  797.     /* Throw away missing values if NOMISS on datasets */
  798.     gr_thrownomiss();
  799.  
  800.     /* Lets do any filling now. */
  801.     draw_fills();
  802.     g_move(ox,oy);        /* move back to the origin x,y */
  803.  
  804.     /* draw the bars */
  805.     zzzz("step2 ");
  806.     draw_bars();
  807.     zzzz("step3 ");
  808.     g_move(ox,oy);        /* move back to the origin x,y */
  809.  
  810.     /* Draw SHADE (psuedo contours) , shade patterns */
  811.  
  812.  
  813.  
  814.     /* Draw the lines and  markers */
  815.     draw_lines();
  816.         zzzz("step4 ");
  817.  
  818.     g_move(ox,oy);        /* move back to the origin x,y */
  819.  
  820.     /* Draw the error bars */
  821.     draw_err();
  822.     g_move(ox,oy);        /* move back to the origin x,y */
  823.     zzzz("step5 ");
  824.  
  825.     /* Draw markers, */
  826.     /* (after lines so symbol blanking [white markers] will work) */
  827.     draw_markers();
  828.     if (abort_key()) goto graph_abort;
  829.     g_move(ox,oy);        /* move back to the origin x,y */
  830.            zzzz("step56");
  831.  
  832.     if (!done_line) {
  833.         g_hint("You must specify in a DN command wether to draw LINES, or MARKERS");
  834.         g_hint("e.g.   D3 LINE    or    D2 MARKER TRIANGLE");
  835.     }
  836.  
  837.     graph_freedata(); freedata = true;
  838.     /* Draw axises */
  839.     {
  840.         double h;
  841.  
  842.         h = g_fontsz;
  843.         for (i=1;i<=4;i++) if (xx[i].base==0) xx[i].base= h;
  844.         xx[1].length = xlength;
  845.         xx[2].length = ylength;
  846.         xx[3].length = xlength;
  847.         xx[4].length = ylength;
  848.     }
  849.     xx[3].type = 3;
  850.     xx[4].type = 4;
  851.  
  852.     g_move(ox,oy);        /* move back to the origin x,y */
  853.     g_move(xbl,ybl);
  854.     draw_axis(&xx[1]);
  855.     if (abort_key()) goto graph_abort;
  856.     g_move(xbl,ybl);
  857.     draw_axis(&xx[2]);
  858.     if (abort_key()) goto graph_abort;
  859.     g_move(xbl,ybl+ylength);
  860.     draw_axis(&xx[3]);
  861.     if (abort_key()) goto graph_abort;
  862.     g_move(xbl+xlength,ybl);
  863.     draw_axis(&xx[4]);
  864.     if (abort_key()) goto graph_abort;
  865.  
  866.     if (*kpos==0) strcpy(kpos,"TR");
  867.     if (khei==0) khei = g_fontsz;
  868.     g_move(ox,oy);
  869.     gdraw_key(koffsetx,koffsety,kpos,khei,knobox);
  870. graph_abort:
  871.     if (freedata==false) graph_freedata();
  872.     g_move(ox,oy);
  873.     graph_free(); /* free memory, and initialize counters for next graph */
  874.     g_grestore();
  875. return;
  876. }
  877.  
  878. graph_init(void) /* Init all counters for next graph */
  879. {
  880.     range_x1 = range_y1 = 1e30; range_x2 = range_y2 = -1e30;
  881.     ndata = 0;
  882.     nfd = 0;
  883.     g_nbar = 0;
  884. }
  885. graph_freedata(void)
  886. {
  887.     int i,j;
  888.     for (i=1;i<=g_nbar;i++) { myfree(br[i]); br[i] = 0; }
  889.     for (i=1;i<=nfd;i++) {myfree(fd[i]); fd[i] = 0; }
  890.     for (i=0;i<=ndata;i++) {
  891.         if (dp[i]!=NULL) {
  892.             iffree(dp[i]->xv,"b");
  893.             iffree(dp[i]->yv,"c");
  894.             iffree(dp[i]->miss,"d");
  895.             dp[i]->xv = 0;
  896.             dp[i]->yv = 0;
  897.             dp[i]->miss = 0;
  898.         }
  899.     }
  900.     free_temp();
  901. }
  902. graph_free(void) /* free memory, */
  903. {
  904.     int i,j;
  905.  
  906.     for (i=0;i<=ndata;i++) {
  907.         if (dp[i]!=NULL) {
  908.             iffree(dp[i]->key_name,"a");
  909.             iffree(dp[i]->bigfile,"a");
  910.             iffree(dp[i]->xv,"b");
  911.             iffree(dp[i]->yv,"c");
  912.             iffree(dp[i]->miss,"d");
  913.             myfrees(dp[i],"dp");
  914.         }
  915.         dp[i] = 0;
  916.     }
  917.     for (i=1;i<=4;i++) {
  918.       iffree(xx[i].title,"t");
  919.       for (j=0;j<=xx[i].nnam;j++) {
  920.         iffree(xx[i].names[j],"q");
  921.         xx[i].names[j] = NULL;
  922.       }
  923.     }
  924. }
  925. iffree(void *p, char *s)
  926. {
  927.     if (p!=NULL) myfrees(p,s);
  928. }
  929. set_sizelength()
  930. {
  931.     /* ! set up some more constants */
  932.     double ox,oy;
  933.     g_get_xy(&ox,&oy);    /* get the origin x,y */
  934.     if (g_hscale==0) g_hscale = .7;
  935.     if (g_vscale==0) g_vscale = .7;
  936.  
  937.     xbl = ox + (g_xsize/2)-(g_xsize*g_hscale/2);
  938.     ybl = oy + (g_ysize/2)-(g_ysize*g_vscale/2);
  939.     xlength = g_xsize*g_hscale;
  940.     ylength = g_ysize*g_vscale;
  941.     g_fontsz = ylength/23;
  942.  
  943. }
  944. freedataset(int d)
  945. {
  946.     int i,c=0;
  947.     for (i=1;i<=ndata;i++) {
  948.         if (dp[i] == NULL) c++;
  949.         else if (dp[i]->xv == NULL) c++;
  950.         if (c==d) return i;
  951.     }
  952.     return ndata + d - c;
  953. }
  954. alloc_temp(int ntmp)
  955. {
  956.     double *a;
  957.     int *b;
  958.     if (ntmp < (ntmp_alloc-20)) return;
  959.     ntmp_alloc = 50 + 2 * ntmp;
  960.     a = myallocn(ntmp_alloc,sizeof(double));
  961.     b = myallocn(ntmp_alloc,sizeof(int));
  962. /*    if (a==0 || b==0) {
  963.         gprint("Unable to allocate memory for dataset \n");
  964.         gle_abort("No memory for dataset\n");
  965.     }
  966. */
  967.     if (tmpf != NULL) {
  968.         memcpy(a,tmpf,(2+ntmp)*sizeof(double));
  969.         memcpy(b,tmpmiss,(2+ntmp)*sizeof(int));
  970.         myfrees(tmpf,"tmpfree"); myfree(tmpmiss);
  971.     }
  972.     tmpf = a; tmpmiss = b;
  973. }
  974. free_temp()
  975. {
  976.     if (tmpf==NULL) return;
  977.     myfrees(tmpf,"tmpfree2"); myfree(tmpmiss);
  978.     tmpf = 0; tmpmiss = 0;
  979.     ntmp_alloc = 0;
  980. }
  981. copy_default(int dn)
  982. {
  983.     memcpy(dp[dn],dp[0],sizeof(*dp[0]));
  984.     dp[dn]->key_name = NULL;
  985.     dp[dn]->bigfile = NULL;
  986.     dp[dn]->xv = NULL;
  987.     dp[dn]->yv = NULL;
  988.     dp[dn]->miss = NULL;
  989. }
  990.