home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / GPT34SRC / MISC.C < prev    next >
C/C++ Source or Header  |  1993-05-25  |  27KB  |  949 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: misc.c%v 3.38.2.120 1993/04/26 00:25:11 woo Exp woo $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - misc.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  *
  25.  *   Original Software:
  26.  *     Thomas Williams,  Colin Kelley.
  27.  * 
  28.  *   Gnuplot 2.0 additions:
  29.  *       Russell Lang, Dave Kotz, John Campbell.
  30.  *
  31.  *   Gnuplot 3.0 additions:
  32.  *       Gershon Elber and many others.
  33.  *
  34.  */
  35.  
  36. #include <stdio.h>
  37. #include <math.h>
  38. #ifndef __PUREC__
  39. #ifndef VMS
  40. #ifdef AMIGA_AC_5
  41. #include <exec/types.h>
  42. #else
  43. #include <sys/types.h>
  44. #endif /* AMIGA_AC_5 */
  45. #else
  46. #include <types.h>
  47. #endif
  48. #endif /* __PUREC__ */
  49. #include "plot.h"
  50. #include "setshow.h"
  51. #ifndef _Windows
  52. #include "help.h"
  53. #endif
  54.  
  55. #if !defined(__TURBOC__) && !defined (_IBMR2) && !defined (ATARI) && !defined (AMIGA_SC_6_1) && !defined(OSF1)
  56. extern char *malloc();
  57. extern char *realloc();
  58. #endif
  59.  
  60. #if defined(__TURBOC__) && (defined(MSDOS) || defined(_Windows))
  61. #include <alloc.h>        /* for malloc, farmalloc, farrealloc */
  62. #endif
  63. #if defined(sequent)
  64. #include <sys/types.h>          /* typedef long size_t; */
  65. #endif
  66.  
  67. extern int c_token;
  68. extern char replot_line[];
  69. extern struct at_type at;
  70. extern struct ft_entry ft[];
  71. extern struct udft_entry *first_udf;
  72. extern struct udvt_entry *first_udv;
  73.  
  74. extern struct at_type *temp_at();
  75.  
  76. extern TBOOLEAN interactive;
  77. extern char *infile_name;
  78. extern int inline_num;
  79.  
  80. /* State information for load_file(), to recover from errors
  81.  * and properly handle recursive load_file calls
  82.  */
  83. typedef struct lf_state_struct LFS;
  84. struct lf_state_struct {
  85.     FILE *fp;                /* file pointer for load file */
  86.     char *name;            /* name of file */
  87.     TBOOLEAN interactive;        /* value of interactive flag on entry */
  88.     int inline_num;            /* inline_num on entry */
  89.     LFS *prev;                /* defines a stack */
  90. } *lf_head = NULL;            /* NULL if not in load_file */
  91.  
  92. static TBOOLEAN lf_pop();
  93. static void lf_push();
  94. FILE *lf_top();
  95.  
  96.  
  97. /*
  98.  * instead of <strings.h>
  99.  */
  100. #ifdef _Windows
  101. #include <string.h>
  102. #else
  103. #ifndef AMIGA_SC_6_1
  104. extern int strcmp();
  105. #endif /* !AMIGA_SC_6_1 */
  106. #endif
  107.  
  108. /* alloc:
  109.  * allocate memory 
  110.  * This is a protected version of malloc. It causes an int_error 
  111.  * if there is not enough memory, but first it tries FreeHelp() 
  112.  * to make some room, and tries again. If message is NULL, we 
  113.  * allow NULL return. Otherwise, we handle the error, using the
  114.  * message to create the int_error string. Note cp/sp_extend uses realloc,
  115.  * so it depends on this using malloc().
  116.  */
  117.  
  118. char *
  119. alloc(size, message)
  120.     unsigned long size;        /* # of bytes */
  121.     char *message;            /* description of what is being allocated */
  122. {
  123.     char *p;                /* the new allocation */
  124.     char errbuf[100];        /* error message string */
  125.  
  126.     p = malloc((size_t)size);
  127.     if (p == (char *)NULL) {
  128. #ifndef vms
  129. #ifndef _Windows
  130.        FreeHelp();            /* out of memory, try to make some room */
  131. #endif
  132. #endif
  133.        p = malloc((size_t)size);        /* try again */
  134.        if (p == (char *)NULL) {
  135.           /* really out of memory */
  136.           if (message != NULL) {
  137.              (void) sprintf(errbuf, "out of memory for %s", message);
  138.              int_error(errbuf, NO_CARET);
  139.              /* NOTREACHED */
  140.           }
  141.           /* else we return NULL */
  142.        }
  143.     }
  144.     return(p);
  145. }
  146.  
  147. /*
  148.  * cp_alloc() allocates a curve_points structure that can hold 'num'
  149.  * points.
  150.  */
  151. struct curve_points *
  152. cp_alloc(num)
  153.     int num;
  154. {
  155.     struct curve_points *cp;
  156.     cp = (struct curve_points *) alloc((unsigned long)sizeof(struct curve_points), "curve");
  157.     cp->p_max = (num >= 0 ? num : 0);
  158.     if (num > 0) {
  159.        cp->points = (struct coordinate GPHUGE *)
  160.         gpfaralloc((unsigned long)num * sizeof(struct coordinate), "curve points");
  161.     } else
  162.        cp->points = (struct coordinate GPHUGE *) NULL;
  163.     cp->next_cp = NULL;
  164.     cp->title = NULL;
  165.     return(cp);
  166. }
  167.  
  168.  
  169. /*
  170.  * cp_extend() reallocates a curve_points structure to hold "num"
  171.  * points. This will either expand or shrink the storage.
  172.  */
  173. cp_extend(cp, num)
  174.     struct curve_points *cp;
  175.     int num;
  176. {
  177.     struct coordinate GPHUGE *new;
  178.  
  179. #if (defined(MSDOS) || defined(_Windows))  &&  !defined(WIN32)
  180.     /* Make sure we do not allocate more than 64k points in msdos since 
  181.      * indexing is done with 16-bit int
  182.      * Leave some bytes for malloc maintainance.
  183.      */
  184.     if (num > 32700)
  185.         int_error("Array index must be less than 32k in msdos", NO_CARET);
  186. #endif /* MSDOS */
  187.  
  188.     if (num == cp->p_max) return(0);
  189.  
  190.     if (num > 0) {
  191.        if (cp->points == NULL) {
  192.           cp->points = (struct coordinate GPHUGE *)
  193.             gpfaralloc((unsigned long)num * sizeof(struct coordinate), "curve points");
  194.        } else {
  195.           new = (struct coordinate GPHUGE *)
  196.             gpfarrealloc(cp->points, (unsigned long)num * sizeof(struct coordinate));
  197.           if (new == (struct coordinate GPHUGE *) NULL) {
  198.              int_error("No memory available for expanding curve points",
  199.                      NO_CARET);
  200.              /* NOTREACHED */
  201.           }
  202.           cp->points = new;
  203.        }
  204.        cp->p_max = num;
  205.     } else {
  206.        if (cp->points != (struct coordinate GPHUGE *) NULL)
  207.         gpfarfree(cp->points);
  208.        cp->points = (struct coordinate GPHUGE *) NULL;
  209.        cp->p_max = 0;
  210.     }
  211. }
  212.  
  213. /*
  214.  * cp_free() releases any memory which was previously malloc()'d to hold
  215.  *   curve points (and recursively down the linked list).
  216.  */
  217. cp_free(cp)
  218. struct curve_points *cp;
  219. {
  220.     if (cp) {
  221.         cp_free(cp->next_cp);
  222.         if (cp->title)
  223.             free((char *)cp->title);
  224.         if (cp->points)
  225.             gpfarfree((char *)cp->points);
  226.         free((char *)cp);
  227.     }
  228. }
  229.  
  230. /*
  231.  * iso_alloc() allocates a iso_curve structure that can hold 'num'
  232.  * points.
  233.  */
  234. struct iso_curve *
  235. iso_alloc(num)
  236.     int num;
  237. {
  238.     struct iso_curve *ip;
  239.     ip = (struct iso_curve *) alloc((unsigned long)sizeof(struct iso_curve), "iso curve");
  240.     ip->p_max = (num >= 0 ? num : 0);
  241.     if (num > 0) {
  242.        ip->points = (struct coordinate GPHUGE *)
  243.         gpfaralloc((unsigned long)num * sizeof(struct coordinate), "iso curve points");
  244.     } else
  245.        ip->points = (struct coordinate GPHUGE *) NULL;
  246.     ip->next = NULL;
  247.     return(ip);
  248. }
  249.  
  250. /*
  251.  * iso_extend() reallocates a iso_curve structure to hold "num"
  252.  * points. This will either expand or shrink the storage.
  253.  */
  254. iso_extend(ip, num)
  255.     struct iso_curve *ip;
  256.     int num;
  257. {
  258.     struct coordinate GPHUGE *new;
  259.  
  260.     if (num == ip->p_max) return(0);
  261.  
  262. #if (defined(MSDOS) || defined(_Windows))  &&  !defined(WIN32)
  263.     /* Make sure we do not allocate more than 64k points in msdos since 
  264.      * indexing is done with 16-bit int
  265.      * Leave some bytes for malloc maintainance.
  266.      */
  267.     if (num > 32700)
  268.         int_error("Array index must be less than 32k in msdos", NO_CARET);
  269. #endif /* MSDOS */
  270.  
  271.     if (num > 0) {
  272.        if (ip->points == NULL) {
  273.           ip->points = (struct coordinate GPHUGE *)
  274.             gpfaralloc((unsigned long)num * sizeof(struct coordinate), "iso curve points");
  275.        } else {
  276.           new = (struct coordinate GPHUGE *)
  277.             gpfarrealloc(ip->points, (unsigned long)num * sizeof(struct coordinate));
  278.           if (new == (struct coordinate GPHUGE *) NULL) {
  279.              int_error("No memory available for expanding curve points",
  280.                      NO_CARET);
  281.              /* NOTREACHED */
  282.           }
  283.           ip->points = new;
  284.        }
  285.        ip->p_max = num;
  286.     } else {
  287.        if (ip->points != (struct coordinate GPHUGE *) NULL)
  288.         gpfarfree(ip->points);
  289.        ip->points = (struct coordinate GPHUGE *) NULL;
  290.        ip->p_max = 0;
  291.     }
  292. }
  293.  
  294. /*
  295.  * iso_free() releases any memory which was previously malloc()'d to hold
  296.  *   iso curve points.
  297.  */
  298. iso_free(ip)
  299. struct iso_curve *ip;
  300. {
  301.     if (ip) {
  302.         if (ip->points)
  303.             gpfarfree((char *)ip->points);
  304.         free((char *)ip);
  305.     }
  306. }
  307.  
  308. /*
  309.  * sp_alloc() allocates a surface_points structure that can hold 'num_iso_1'
  310.  * iso-curves with 'num_samp_2' samples and 'num_iso_2' iso-curves with
  311.  * 'num_samp_1' samples.
  312.  * If, however num_iso_2 or num_samp_1 is zero no iso curves are allocated.
  313.  */
  314. struct surface_points *
  315. sp_alloc(num_samp_1,num_iso_1,num_samp_2,num_iso_2)
  316.     int num_samp_1,num_iso_1,num_samp_2,num_iso_2;
  317. {
  318.     struct surface_points *sp;
  319.  
  320.     sp = (struct surface_points *) alloc((unsigned long)sizeof(struct surface_points), "surface");
  321.     sp->next_sp = NULL;
  322.     sp->title = NULL;
  323.     sp->contours = NULL;
  324.     sp->iso_crvs = NULL;
  325.     sp->num_iso_read = 0;
  326.  
  327.     if (num_iso_2 > 0 && num_samp_1 > 0) {
  328.     int i;
  329.     struct iso_curve *icrv;
  330.  
  331.     for (i = 0; i < num_iso_1; i++) {
  332.         icrv = iso_alloc(num_samp_2);
  333.         icrv->next = sp->iso_crvs;
  334.         sp->iso_crvs = icrv;
  335.     }
  336.     for (i = 0; i < num_iso_2; i++) {
  337.         icrv = iso_alloc(num_samp_1);
  338.         icrv->next = sp->iso_crvs;
  339.         sp->iso_crvs = icrv;
  340.     }
  341.     } else
  342.     sp->iso_crvs = (struct iso_curve *) NULL;
  343.  
  344.     return(sp);
  345. }
  346.  
  347. /*
  348.  * sp_replace() updates a surface_points structure so it can hold 'num_iso_1'
  349.  * iso-curves with 'num_samp_2' samples and 'num_iso_2' iso-curves with
  350.  * 'num_samp_1' samples.
  351.  * If, however num_iso_2 or num_samp_1 is zero no iso curves are allocated.
  352.  */
  353. sp_replace(sp,num_samp_1,num_iso_1,num_samp_2,num_iso_2)
  354.        struct surface_points *sp;
  355.        int num_samp_1,num_iso_1,num_samp_2,num_iso_2;
  356. {
  357.     int i;
  358.     struct iso_curve *icrv, *icrvs = sp->iso_crvs;
  359.  
  360.     while ( icrvs ) {
  361.     icrv = icrvs;
  362.     icrvs = icrvs->next;
  363.     iso_free( icrv );
  364.     }
  365.     sp->iso_crvs = NULL;
  366.     
  367.     if (num_iso_2 > 0 && num_samp_1 > 0) {
  368.     for (i = 0; i < num_iso_1; i++) {
  369.         icrv = iso_alloc(num_samp_2);
  370.         icrv->next = sp->iso_crvs;
  371.         sp->iso_crvs = icrv;
  372.     }
  373.     for (i = 0; i < num_iso_2; i++) {
  374.         icrv = iso_alloc(num_samp_1);
  375.         icrv->next = sp->iso_crvs;
  376.         sp->iso_crvs = icrv;
  377.     }
  378.     } else
  379.     sp->iso_crvs = (struct iso_curve *) NULL;
  380. }
  381.  
  382. /*
  383.  * sp_free() releases any memory which was previously malloc()'d to hold
  384.  *   surface points.
  385.  */
  386. sp_free(sp)
  387. struct surface_points *sp;
  388. {
  389.     if (sp) {
  390.         sp_free(sp->next_sp);
  391.         if (sp->title)
  392.             free((char *)sp->title);
  393.         if (sp->contours) {
  394.             struct gnuplot_contours *cntr, *cntrs = sp->contours;
  395.  
  396.             while (cntrs) {
  397.                 cntr = cntrs;
  398.                 cntrs = cntrs->next;
  399.                 gpfarfree(cntr->coords);
  400.                 free(cntr);
  401.             }
  402.         }
  403.         if (sp->iso_crvs) {
  404.             struct iso_curve *icrv, *icrvs = sp->iso_crvs;
  405.  
  406.             while (icrvs) {
  407.                 icrv = icrvs;
  408.                 icrvs = icrvs->next;
  409.                 iso_free(icrv);
  410.             }
  411.         }
  412.         free((char *)sp);
  413.     }
  414. }
  415.  
  416.  
  417.  
  418. save_functions(fp)
  419. FILE *fp;
  420. {
  421. register struct udft_entry *udf = first_udf;
  422.  
  423.     if (fp) {
  424.         while (udf) {
  425.             if (udf->definition)
  426.                 fprintf(fp,"%s\n",udf->definition);
  427.             udf = udf->next_udf;
  428.         }
  429.         (void) fclose(fp);
  430.     } else
  431.         os_error("Cannot open save file",c_token);            
  432. }
  433.  
  434.  
  435. save_variables(fp)
  436. FILE *fp;
  437. {
  438. register struct udvt_entry *udv = first_udv->next_udv;    /* skip pi */
  439.  
  440.     if (fp) {
  441.         while (udv) {
  442.             if (!udv->udv_undef) {
  443.                 fprintf(fp,"%s = ",udv->udv_name);
  444.                 disp_value(fp,&(udv->udv_value));
  445.                 (void) putc('\n',fp);
  446.             }
  447.             udv = udv->next_udv;
  448.         }
  449.         (void) fclose(fp);
  450.     } else
  451.         os_error("Cannot open save file",c_token);            
  452. }
  453.  
  454.  
  455. save_all(fp)
  456. FILE *fp;
  457. {
  458. register struct udft_entry *udf = first_udf;
  459. register struct udvt_entry *udv = first_udv->next_udv;    /* skip pi */
  460.  
  461.     if (fp) {
  462.         save_set_all(fp);
  463.         while (udf) {
  464.             if (udf->definition)
  465.                 fprintf(fp,"%s\n",udf->definition);
  466.             udf = udf->next_udf;
  467.         }
  468.         while (udv) {
  469.             if (!udv->udv_undef) {
  470.                 fprintf(fp,"%s = ",udv->udv_name);
  471.                 disp_value(fp,&(udv->udv_value));
  472.                 (void) putc('\n',fp);
  473.             }
  474.             udv = udv->next_udv;
  475.         }
  476.         fprintf(fp,"%s\n",replot_line);
  477.         (void) fclose(fp);
  478.     } else
  479.         os_error("Cannot open save file",c_token);            
  480. }
  481.  
  482.  
  483. save_set(fp)
  484. FILE *fp;
  485. {
  486.     if (fp) {
  487.         save_set_all(fp);
  488.         (void) fclose(fp);
  489.     } else
  490.         os_error("Cannot open save file",c_token);            
  491. }
  492.  
  493.  
  494. save_set_all(fp)
  495. FILE *fp;
  496. {
  497. struct text_label *this_label;
  498. struct arrow_def *this_arrow;
  499. char *quote;
  500.     fprintf(fp,"set terminal %s %s\n", term_tbl[term].name, term_options);
  501.     fprintf(fp,"set output %s\n",strcmp(outstr,"STDOUT")? outstr : "" );
  502.     fprintf(fp,"set %sclip points\n", (clip_points)? "" : "no");
  503.     fprintf(fp,"set %sclip one\n", (clip_lines1)? "" : "no");
  504.     fprintf(fp,"set %sclip two\n", (clip_lines2)? "" : "no");
  505.     fprintf(fp,"set %sborder\n",draw_border ? "" : "no");
  506.     if (boxwidth<0.0)
  507.         fprintf(fp,"set boxwidth\n");
  508.     else
  509.         fprintf(fp,"set boxwidth %g\n",boxwidth);
  510.     fprintf(fp,"set dummy %s,%s\n",dummy_var[0], dummy_var[1]);
  511.     fprintf(fp,"set format x \"%s\"\n", xformat);
  512.     fprintf(fp,"set format y \"%s\"\n", yformat);
  513.     fprintf(fp,"set format z \"%s\"\n", zformat);
  514.     fprintf(fp,"set %sgrid\n", (grid)? "" : "no");
  515.     switch (key) {
  516.         case -1 :
  517.             fprintf(fp,"set key\n");
  518.             break;
  519.         case 0 :
  520.             fprintf(fp,"set nokey\n");
  521.             break;
  522.         case 1 :
  523.             fprintf(fp,"set key %g,%g,%g\n",key_x,key_y,key_z);
  524.             break;
  525.     }
  526.     fprintf(fp,"set nolabel\n");
  527.     for (this_label = first_label; this_label != NULL;
  528.             this_label = this_label->next) {
  529.         fprintf(fp,"set label %d \"%s\" at %g,%g,%g ",
  530.                this_label->tag,
  531.                this_label->text, this_label->x,
  532.                          this_label->y,
  533.                          this_label->z);
  534.         switch(this_label->pos) {
  535.             case LEFT :
  536.                 fprintf(fp,"left");
  537.                 break;
  538.             case CENTRE :
  539.                 fprintf(fp,"centre");
  540.                 break;
  541.             case RIGHT :
  542.                 fprintf(fp,"right");
  543.                 break;
  544.         }
  545.         fputc('\n',fp);
  546.     }
  547.     fprintf(fp,"set noarrow\n");
  548.     for (this_arrow = first_arrow; this_arrow != NULL;
  549.             this_arrow = this_arrow->next) {
  550.         fprintf(fp,"set arrow %d from %g,%g,%g to %g,%g,%g%s\n",
  551.                this_arrow->tag,
  552.                this_arrow->sx, this_arrow->sy, this_arrow->sz,
  553.                this_arrow->ex, this_arrow->ey, this_arrow->ez,
  554.                this_arrow->head ? "" : " nohead");
  555.     }
  556.     fprintf(fp,"set nologscale\n");
  557.     if (is_log_x) fprintf(fp,"set logscale x %g\n", base_log_x);
  558.     if (is_log_y) fprintf(fp,"set logscale y %g\n", base_log_y);
  559.     if (is_log_z) fprintf(fp,"set logscale z %g\n", base_log_z);
  560.     fprintf(fp,"set offsets %g, %g, %g, %g\n",loff,roff,toff,boff);
  561.     fprintf(fp,"set %spolar\n", (polar)? "" : "no");
  562.     fprintf(fp,"set angles %s\n", (angles_format == ANGLES_RADIANS)?
  563.                         "radians" : "degrees");
  564.     fprintf(fp,"set %sparametric\n", (parametric)? "" : "no");
  565.     fprintf(fp,"set view %g, %g, %g, %g\n",
  566.         surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
  567.     fprintf(fp,"set samples %d, %d\n",samples_1,samples_2);
  568.     fprintf(fp,"set isosamples %d, %d\n",iso_samples_1,iso_samples_2);
  569.     fprintf(fp,"set %ssurface\n",(draw_surface) ? "" : "no");
  570.     fprintf(fp,"set %scontour",(draw_contour) ? "" : "no");
  571.     switch (draw_contour) {
  572.         case CONTOUR_NONE: fprintf(fp, "\n"); break;
  573.         case CONTOUR_BASE: fprintf(fp, " base\n"); break;
  574.         case CONTOUR_SRF:  fprintf(fp, " surface\n"); break;
  575.         case CONTOUR_BOTH: fprintf(fp, " both\n"); break;
  576.     }
  577.      fprintf(fp,"set %sclabel\n",(label_contours) ? "" : "no");
  578.     fprintf(fp,"set %shidden3d\n",(hidden3d) ? "" : "no");
  579.     fprintf(fp,"set cntrparam order %d\n", contour_order);
  580.     fprintf(fp,"set cntrparam ");
  581.     switch (contour_kind) {
  582.         case CONTOUR_KIND_LINEAR:    fprintf(fp, "linear\n"); break;
  583.         case CONTOUR_KIND_CUBIC_SPL: fprintf(fp, "cubicspline\n"); break;
  584.         case CONTOUR_KIND_BSPLINE:   fprintf(fp, "bspline\n"); break;
  585.     }
  586.     fprintf(fp,"set cntrparam levels ");
  587.     switch (levels_kind) {
  588.         int i;
  589.         case LEVELS_AUTO:
  590.             fprintf(fp, "auto %d\n", contour_levels);
  591.             break;
  592.         case LEVELS_INCREMENTAL:
  593.             fprintf(fp, "incremental %g,%g,%g\n",
  594.                 levels_list[0], levels_list[1], 
  595.                 levels_list[0]+levels_list[1]*contour_levels);
  596.             break;
  597.         case LEVELS_DISCRETE:
  598.             fprintf(fp, "discrete ");
  599.                 fprintf(fp, "%g", levels_list[0]);
  600.             for(i = 1; i < contour_levels; i++)
  601.                 fprintf(fp, ",%g ", levels_list[i]);
  602.             fprintf(fp, "\n");
  603.     }
  604.     fprintf(fp,"set cntrparam points %d\n", contour_pts);
  605.     fprintf(fp,"set size %g,%g\n",xsize,ysize);
  606.     fprintf(fp,"set data style ");
  607.     switch (data_style) {
  608.         case LINES: fprintf(fp,"lines\n"); break;
  609.         case POINTSTYLE: fprintf(fp,"points\n"); break;
  610.         case IMPULSES: fprintf(fp,"impulses\n"); break;
  611.         case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
  612.         case DOTS: fprintf(fp,"dots\n"); break;
  613.         case ERRORBARS: fprintf(fp,"errorbars\n"); break;
  614.         case BOXES: fprintf(fp,"boxes\n"); break;
  615.         case BOXERROR: fprintf(fp,"boxerrorbars\n"); break;
  616.         case STEPS: fprintf(fp,"steps\n"); break;       /* JG */
  617.     }
  618.     fprintf(fp,"set function style ");
  619.     switch (func_style) {
  620.         case LINES: fprintf(fp,"lines\n"); break;
  621.         case POINTSTYLE: fprintf(fp,"points\n"); break;
  622.         case IMPULSES: fprintf(fp,"impulses\n"); break;
  623.         case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
  624.         case DOTS: fprintf(fp,"dots\n"); break;
  625.         case ERRORBARS: fprintf(fp,"errorbars\n"); break;
  626.         case BOXES: fprintf(fp,"boxes\n"); break;
  627.         case BOXERROR: fprintf(fp,"boxerrorbars\n"); break;
  628.         case STEPS: fprintf(fp,"steps\n"); break;       /* JG */
  629.     }
  630.         fprintf(fp,"set %sxzeroaxis\n", (xzeroaxis)? "" : "no");
  631.         fprintf(fp,"set %syzeroaxis\n", (yzeroaxis)? "" : "no");
  632.         fprintf(fp,"set tics %s\n", (tic_in)? "in" : "out");
  633.         fprintf(fp,"set ticslevel %g\n", ticslevel);
  634.         save_tics(fp, xtics, 'x', &xticdef);
  635.         save_tics(fp, ytics, 'y', &yticdef);
  636.         save_tics(fp, ztics, 'z', &zticdef);
  637.         for (quote = &(title[0]); quote && *quote && (*quote != '"'); quote++)
  638.             ;
  639.         fprintf(fp,"set title %c%s%c %d,%d\n",*quote ? '\'' : '"',title,*quote ? '\'' : '"',title_xoffset,title_yoffset);
  640.     
  641.         if (timedate)
  642.         fprintf(fp,"set time %d,%d\n",time_xoffset,time_yoffset);
  643.     else
  644.         fprintf(fp,"set notime\n");
  645.      fprintf(fp,"set rrange [%g : %g]\n",rmin,rmax);
  646.     fprintf(fp,"set trange [%g : %g]\n",tmin,tmax);
  647.     fprintf(fp,"set urange [%g : %g]\n",umin,umax);
  648.     fprintf(fp,"set vrange [%g : %g]\n",vmin,vmax);
  649.         for (quote = &(xlabel[0]); quote && *quote && (*quote != '"'); quote++)
  650.             ;
  651.         fprintf(fp,"set xlabel %c%s%c %d,%d\n",*quote ? '\'' : '"',xlabel,*quote ? '\'' : '"',xlabel_xoffset,xlabel_yoffset);
  652.         fprintf(fp,"set xrange [%g : %g]\n",xmin,xmax);
  653.         for (quote = &(ylabel[0]); quote && *quote && (*quote != '"'); quote++)
  654.             ;
  655.         fprintf(fp,"set ylabel %c%s%c %d,%d\n",*quote ? '\'' : '"',ylabel,*quote ? '\'' : '"',ylabel_xoffset,ylabel_yoffset);
  656.         fprintf(fp,"set yrange [%g : %g]\n",ymin,ymax);
  657.         for (quote = &(zlabel[0]); quote && *quote && (*quote != '"'); quote++)
  658.             ;
  659.         fprintf(fp,"set zlabel %c%s%c %d,%d\n",*quote ? '\'' : '"',zlabel,*quote ? '\'' : '"',zlabel_xoffset,zlabel_yoffset);
  660.     fprintf(fp,"set zrange [%g : %g]\n",zmin,zmax);
  661.     fprintf(fp,"set %s %c\n", 
  662.         autoscale_r ? "autoscale" : "noautoscale", 'r');
  663.     fprintf(fp,"set %s %c\n", 
  664.         autoscale_t ? "autoscale" : "noautoscale", 't');
  665.     fprintf(fp,"set %s %c%c\n", 
  666.         (autoscale_y||autoscale_x) ? "autoscale" : "noautoscale", 
  667.         autoscale_x ? 'x' : ' ', autoscale_y ? 'y' : ' ');
  668.     fprintf(fp,"set %s %c\n", 
  669.         autoscale_z ? "autoscale" : "noautoscale", 'z');
  670.     fprintf(fp,"set zero %g\n",zero);
  671. }
  672.  
  673. save_tics(fp, onoff, axis, tdef)
  674.     FILE *fp;
  675.     TBOOLEAN onoff;
  676.     char axis;
  677.     struct ticdef *tdef;
  678. {
  679.     if (onoff) {
  680.        fprintf(fp,"set %ctics", axis);
  681.        switch(tdef->type) {
  682.           case TIC_COMPUTED: {
  683.              break;
  684.           }
  685.           case TIC_MONTH:{
  686.               fprintf(fp,"\nset %cmtics",axis);
  687.             break;
  688.           }
  689.             case TIC_DAY:{
  690.             fprintf(fp,"\nset %cdtics",axis);
  691.             break;
  692.             }
  693.           case TIC_SERIES: {
  694.                  if (tdef->def.series.end >= VERYLARGE)
  695.                  fprintf(fp, " %g,%g", tdef->def.series.start,
  696.                                         tdef->def.series.incr);
  697.                          else
  698.                  fprintf(fp, " %g,%g,%g", tdef->def.series.start,
  699.                                         tdef->def.series.incr, tdef->def.series.end);
  700.              break;
  701.           }
  702.           case TIC_USER: {
  703.              register struct ticmark *t;
  704.              fprintf(fp, " (");
  705.              for (t = tdef->def.user; t != NULL; t=t->next) {
  706.                 if (t->label)
  707.                   fprintf(fp, "\"%s\" ", t->label);
  708.                 if (t->next)
  709.                   fprintf(fp, "%g, ", t->position);
  710.                 else
  711.                   fprintf(fp, "%g", t->position);
  712.              }
  713.              fprintf(fp, ")");
  714.              break;
  715.           } 
  716.        }
  717.        fprintf(fp, "\n");
  718.     } else {
  719.        fprintf(fp,"set no%ctics\n", axis);
  720.     }
  721. }
  722.  
  723. load_file(fp, name)
  724.     FILE *fp;
  725.     char *name;
  726. {
  727.     register int len;
  728.     extern char input_line[];
  729.  
  730.     int start, left;
  731.     int more;
  732.     int stop = FALSE;
  733.  
  734.     lf_push(fp);            /* save state for errors and recursion */
  735.  
  736.     if (fp == (FILE *)NULL) {
  737.        char errbuf[BUFSIZ];
  738.        (void) sprintf(errbuf, "Cannot open load file '%s'", name);
  739.        os_error(errbuf, c_token);
  740.     } else {
  741.        /* go into non-interactive mode during load */
  742.        /* will be undone below, or in load_file_error */
  743.        interactive = FALSE;
  744.        inline_num = 0;
  745.        infile_name = name;
  746.  
  747.        while (!stop) {        /* read all commands in file */
  748.           /* read one command */
  749.           left = MAX_LINE_LEN;
  750.           start = 0;
  751.           more = TRUE;
  752.  
  753.           while (more) {
  754.              if (fgets(&(input_line[start]), left, fp) == (char *)NULL) {
  755.                 stop = TRUE; /* EOF in file */
  756.                 input_line[start] = '\0';
  757.                 more = FALSE;    
  758.              } else {
  759.                 inline_num++;
  760.                 len = strlen(input_line) - 1;
  761.                 if (input_line[len] == '\n') { /* remove any newline */
  762.                     input_line[len] = '\0';
  763.                     /* Look, len was 1-1 = 0 before, take care here! */
  764.                     if (len > 0) --len;
  765.                 } else if (len+1 >= left)
  766.                   int_error("Input line too long",NO_CARET);
  767.                  
  768.                 if (input_line[len] == '\\') { /* line continuation */
  769.                     start = len;
  770.                     left  = MAX_LINE_LEN - start; /* left -=len;*/
  771.                 } else
  772.                   more = FALSE;
  773.              }
  774.           }
  775.  
  776.           if (strlen(input_line) > 0) {
  777.              screen_ok = FALSE;    /* make sure command line is
  778.                                echoed on error */
  779.              do_line();
  780.           }
  781.        }
  782.     }
  783.  
  784.     /* pop state */
  785.     (void) lf_pop();        /* also closes file fp */
  786. }
  787.  
  788. /* pop from load_file state stack */
  789. static TBOOLEAN                /* FALSE if stack was empty */
  790. lf_pop()                    /* called by load_file and load_file_error */
  791. {
  792.     LFS *lf;
  793.  
  794.     if (lf_head == NULL)
  795.      return(FALSE);
  796.     else {
  797.        lf = lf_head;
  798.        if (lf->fp != (FILE *)NULL)
  799.         (void) fclose(lf->fp);
  800.        interactive = lf->interactive;
  801.        inline_num = lf->inline_num;
  802.        infile_name = lf->name;
  803.        lf_head = lf->prev;
  804.        free((char *)lf);
  805.        return(TRUE);
  806.     }
  807. }
  808.  
  809. /* push onto load_file state stack */
  810. /* essentially, we save information needed to undo the load_file changes */
  811. static void
  812. lf_push(fp)            /* called by load_file */
  813.     FILE *fp;
  814. {
  815.     LFS *lf;
  816.     
  817.     lf = (LFS *)alloc((unsigned long)sizeof(LFS), (char *)NULL);
  818.     if (lf == (LFS *)NULL) {
  819.        if (fp != (FILE *)NULL)
  820.         (void) fclose(fp);        /* it won't be otherwise */
  821.        int_error("not enough memory to load file", c_token);
  822.     }
  823.      
  824.     lf->fp = fp;            /* save this file pointer */
  825.     lf->name = infile_name;    /* save current name */
  826.     lf->interactive = interactive;    /* save current state */
  827.     lf->inline_num = inline_num; /* save current line number */
  828.     lf->prev = lf_head;        /* link to stack */
  829.     lf_head = lf;
  830. }
  831.  
  832. FILE *lf_top()        /* used for reread  vsnyder@math.jpl.nasa.gov */
  833. {   if (lf_head == (LFS *) NULL) return((FILE *)NULL);
  834.     return(lf_head->fp);
  835. }
  836.  
  837.  
  838. load_file_error()            /* called from main */
  839. {
  840.     /* clean up from error in load_file */
  841.     /* pop off everything on stack */
  842.     while(lf_pop())
  843.      ;
  844. }
  845.  
  846. /* find char c in string str; return p such that str[p]==c;
  847.  * if c not in str then p=strlen(str)
  848.  */
  849. int
  850. instring(str, c)
  851.     char *str;
  852.     char c;
  853. {
  854.     int pos = 0;
  855.  
  856.     while (str != NULL && *str != '\0' && c != *str) {
  857.        str++; 
  858.        pos++;
  859.     }
  860.     return (pos);
  861. }
  862.  
  863. show_functions()
  864. {
  865. register struct udft_entry *udf = first_udf;
  866.  
  867.     fprintf(stderr,"\n\tUser-Defined Functions:\n");
  868.  
  869.     while (udf) {
  870.         if (udf->definition)
  871.             fprintf(stderr,"\t%s\n",udf->definition);
  872.         else
  873.             fprintf(stderr,"\t%s is undefined\n",udf->udf_name);
  874.         udf = udf->next_udf;
  875.     }
  876. }
  877.  
  878.  
  879. show_at()
  880. {
  881.     (void) putc('\n',stderr);
  882.     disp_at(temp_at(),0);
  883. }
  884.  
  885.  
  886. disp_at(curr_at, level)
  887. struct at_type *curr_at;
  888. int level;
  889. {
  890. register int i, j;
  891. register union argument *arg;
  892.  
  893.     for (i = 0; i < curr_at->a_count; i++) {
  894.         (void) putc('\t',stderr);
  895.         for (j = 0; j < level; j++)
  896.             (void) putc(' ',stderr);    /* indent */
  897.  
  898.             /* print name of instruction */
  899.  
  900.         fputs(ft[(int)(curr_at->actions[i].index)].f_name,stderr);
  901.         arg = &(curr_at->actions[i].arg);
  902.  
  903.             /* now print optional argument */
  904.  
  905.         switch(curr_at->actions[i].index) {
  906.           case PUSH:    fprintf(stderr," %s\n", arg->udv_arg->udv_name);
  907.                     break;
  908.           case PUSHC:    (void) putc(' ',stderr);
  909.                     disp_value(stderr,&(arg->v_arg));
  910.                     (void) putc('\n',stderr);
  911.                     break;
  912.           case PUSHD1:    fprintf(stderr," %c dummy\n",
  913.                       arg->udf_arg->udf_name[0]);
  914.                     break;
  915.           case PUSHD2:    fprintf(stderr," %c dummy\n",
  916.                       arg->udf_arg->udf_name[1]);
  917.                     break;
  918.           case CALL:    fprintf(stderr," %s", arg->udf_arg->udf_name);
  919.                     if(level < 6) {
  920.                     if (arg->udf_arg->at) {
  921.                         (void) putc('\n',stderr);
  922.                         disp_at(arg->udf_arg->at,level+2); /* recurse! */
  923.                     } else
  924.                         fputs(" (undefined)\n",stderr);
  925.                     } else
  926.                         (void) putc('\n',stderr);
  927.                     break;
  928.           case CALLN:    fprintf(stderr," %s", arg->udf_arg->udf_name);
  929.                     if(level < 6) {
  930.                     if (arg->udf_arg->at) {
  931.                         (void) putc('\n',stderr);
  932.                         disp_at(arg->udf_arg->at,level+2); /* recurse! */
  933.                     } else
  934.                         fputs(" (undefined)\n",stderr);
  935.                     } else
  936.                         (void) putc('\n',stderr);
  937.                     break;
  938.           case JUMP:
  939.           case JUMPZ:
  940.           case JUMPNZ:
  941.           case JTERN:
  942.                     fprintf(stderr," +%d\n",arg->j_arg);
  943.                     break;
  944.           default:
  945.                     (void) putc('\n',stderr);
  946.         }
  947.     }
  948. }
  949.