home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Gnuplot 3.5 / source / setshow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-11  |  76.9 KB  |  3,192 lines  |  [TEXT/R*ch]

  1. static char *RCSid = "$Id: setshow.c%v 3.50.1.11 1993/08/10 03:55:03 woo Exp $";
  2.  
  3.  
  4. /* GNUPLOT - setshow.c */
  5. /*
  6.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  7.  *
  8.  * Permission to use, copy, and distribute this software and its
  9.  * documentation for any purpose with or without fee is hereby granted, 
  10.  * provided that the above copyright notice appear in all copies and 
  11.  * that both that copyright notice and this permission notice appear 
  12.  * in supporting documentation.
  13.  *
  14.  * Permission to modify the software is granted, but not the right to
  15.  * distribute the modified code.  Modifications are to be distributed 
  16.  * as patches to released version.
  17.  *  
  18.  * This software is provided "as is" without express or implied warranty.
  19.  * 
  20.  *
  21.  * AUTHORS
  22.  * 
  23.  *   Original Software:
  24.  *     Thomas Williams,  Colin Kelley.
  25.  * 
  26.  *   Gnuplot 2.0 additions:
  27.  *       Russell Lang, Dave Kotz, John Campbell.
  28.  *
  29.  *   Gnuplot 3.0 additions:
  30.  *       Gershon Elber and many others.
  31.  *
  32.  * 19 September 1992  Lawrence Crowl  (crowl@cs.orst.edu)
  33.  * Added user-specified bases for log scaling.
  34.  * 
  35.  * There is a mailing list for gnuplot users. Note, however, that the
  36.  * newsgroup 
  37.  *    comp.graphics.gnuplot 
  38.  * is identical to the mailing list (they
  39.  * both carry the same set of messages). We prefer that you read the
  40.  * messages through that newsgroup, to subscribing to the mailing list.
  41.  * (If you can read that newsgroup, and are already on the mailing list,
  42.  * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  43.  * removed from the mailing list.)
  44.  *
  45.  * The address for mailing to list members is
  46.  *       info-gnuplot@dartmouth.edu
  47.  * and for mailing administrative requests is 
  48.  *       info-gnuplot-request@dartmouth.edu
  49.  * The mailing list for bug reports is 
  50.  *       bug-gnuplot@dartmouth.edu
  51.  * The list of those interested in beta-test versions is
  52.  *       info-gnuplot-beta@dartmouth.edu
  53.  */
  54.  
  55. #include <stdio.h>
  56. #include <math.h>
  57. #include "plot.h"
  58. #include "setshow.h"
  59.  
  60. #define DEF_FORMAT   "%g"    /* default format for tic mark labels */
  61. #define SIGNIF (0.01)        /* less than one hundredth of a tic mark */
  62.  
  63. #ifdef THINK_C
  64. #define THINK_C_1
  65. #endif
  66.  
  67. #ifdef THINK_C_1
  68. /*
  69.  * global variables to hold status of 'set' options
  70.  *
  71.  */
  72. TBOOLEAN        autoscale_r    = TRUE;
  73. TBOOLEAN        autoscale_t    = TRUE;
  74. TBOOLEAN        autoscale_u    = TRUE;
  75. TBOOLEAN        autoscale_v    = TRUE;
  76. TBOOLEAN        autoscale_x    = TRUE;
  77. TBOOLEAN        autoscale_y    = TRUE;
  78. TBOOLEAN        autoscale_z    = TRUE;
  79. TBOOLEAN        autoscale_lt    = TRUE;
  80. TBOOLEAN        autoscale_lu    = TRUE;
  81. TBOOLEAN        autoscale_lv    = TRUE;
  82. TBOOLEAN        autoscale_lx    = TRUE;
  83. TBOOLEAN        autoscale_ly    = TRUE;
  84. TBOOLEAN        autoscale_lz    = TRUE;
  85. double            boxwidth    = -1.0; /* box width (automatic) */
  86. TBOOLEAN         clip_points    = FALSE;
  87. TBOOLEAN         clip_lines1    = TRUE;
  88. TBOOLEAN         clip_lines2    = FALSE;
  89. TBOOLEAN        draw_border    = TRUE;
  90. TBOOLEAN        draw_surface    = TRUE;
  91. TBOOLEAN        timedate    = FALSE;
  92. char            dummy_var[MAX_NUM_VAR][MAX_ID_LEN+1] = { "x", "y" };
  93. char            xformat[MAX_ID_LEN+1] = DEF_FORMAT;
  94. char            yformat[MAX_ID_LEN+1] = DEF_FORMAT;
  95. char            zformat[MAX_ID_LEN+1] = DEF_FORMAT;
  96. enum PLOT_STYLE        data_style    = POINTSTYLE;
  97. enum PLOT_STYLE        func_style    = LINES;
  98. TBOOLEAN        grid        = FALSE;
  99. int            key        = -1;    /* default position */
  100. double            key_x;
  101. double            key_y;    /* user specified position for key */
  102. double            key_z;
  103. TBOOLEAN        is_log_x    = FALSE;
  104. TBOOLEAN        is_log_y    = FALSE;
  105. TBOOLEAN        is_log_z    = FALSE;
  106. double            base_log_x    = 0.0;
  107. double            base_log_y    = 0.0;
  108. double            base_log_z    = 0.0;
  109. double            log_base_log_x    = 0.0;
  110. double            log_base_log_y    = 0.0;
  111. double            log_base_log_z    = 0.0;
  112. FILE*            outfile;
  113. char            outstr[MAX_ID_LEN+1] = "STDOUT";
  114. TBOOLEAN        parametric    = FALSE;
  115. TBOOLEAN        polar        = FALSE;
  116. TBOOLEAN        hidden3d    = FALSE;
  117. TBOOLEAN        label_contours    = TRUE; /* different linestyles are used for contours when set */
  118. int            angles_format    = ANGLES_RADIANS;
  119. int            mapping3d    = MAP3D_CARTESIAN;
  120. int            samples        = SAMPLES; /* samples is always equal to samples_1 */
  121. int            samples_1    = SAMPLES;
  122. int            samples_2    = SAMPLES;
  123. int            iso_samples_1    = ISO_SAMPLES;
  124. int            iso_samples_2    = ISO_SAMPLES;
  125. float            xsize        = 1.0;  /* scale factor for size */
  126. float            ysize        = 1.0;  /* scale factor for size */
  127. float            zsize        = 1.0;  /* scale factor for size */
  128. float            surface_rot_z   = 30.0; /* Default 3d transform. */
  129. float            surface_rot_x   = 60.0;
  130. float            surface_scale   = 1.0;
  131. float            surface_zscale  = 1.0;
  132. int            term        = 0;        /* unknown term is 0 */
  133. char            term_options[MAX_LINE_LEN+1] = "";
  134. char            title[MAX_LINE_LEN+1] = "";
  135. char            xlabel[MAX_LINE_LEN+1] = "";
  136. char            ylabel[MAX_LINE_LEN+1] = "";
  137. char            zlabel[MAX_LINE_LEN+1] = "";
  138. int            time_xoffset    = 0;
  139. int            time_yoffset    = 0;
  140. int            title_xoffset    = 0;
  141. int            title_yoffset    = 0;
  142. int            xlabel_xoffset    = 0;
  143. int            xlabel_yoffset    = 0;
  144. int            ylabel_xoffset    = 0;
  145. int            ylabel_yoffset    = 0;
  146. int            zlabel_xoffset    = 0;
  147. int            zlabel_yoffset    = 0;
  148. double            rmin        = -0.0;
  149. double            rmax        =  10.0;
  150. double            tmin        = -5.0;
  151. double            tmax        =  5.0;
  152. double            umin        = -5.0;
  153. double            umax        = 5.0;
  154. double            vmin        = -5.0;
  155. double            vmax        = 5.0;
  156. double            xmin        = -10.0;
  157. double            xmax        = 10.0;
  158. double            ymin        = -10.0;
  159. double            ymax        = 10.0;
  160. double            zmin        = -10.0;
  161. double            zmax        = 10.0;
  162. double            loff        = 0.0;
  163. double            roff        = 0.0;
  164. double            toff        = 0.0;
  165. double            boff        = 0.0;
  166. int            draw_contour    = CONTOUR_NONE;
  167. int            contour_pts    = 5;
  168. int            contour_kind    = CONTOUR_KIND_LINEAR;
  169. int            contour_order    = 4;
  170. int            contour_levels    = 5;
  171. double            zero        = ZERO;    /* zero threshold, not 0! */
  172. int            levels_kind    = LEVELS_AUTO;
  173. double            levels_list[MAX_DISCRETE_LEVELS];  /* storage for z levels to draw contours at */
  174.  
  175. int            dgrid3d_row_fineness = 10;
  176. int            dgrid3d_col_fineness = 10;
  177. int            dgrid3d_norm_value = 1;
  178. TBOOLEAN        dgrid3d        = FALSE;
  179.  
  180. TBOOLEAN         xzeroaxis    = TRUE;
  181. TBOOLEAN         yzeroaxis    = TRUE;
  182.  
  183. TBOOLEAN         xtics        = TRUE;
  184. TBOOLEAN         ytics        = TRUE;
  185. TBOOLEAN         ztics        = TRUE;
  186.  
  187. float             ticslevel    = 0.5;
  188.  
  189. struct ticdef        xticdef        = {TIC_COMPUTED};
  190. struct ticdef        yticdef        = {TIC_COMPUTED};
  191. struct ticdef        zticdef        = {TIC_COMPUTED};
  192.  
  193. TBOOLEAN        tic_in        = TRUE;
  194.  
  195. struct text_label     *first_label    = NULL;
  196. struct arrow_def     *first_arrow    = NULL;
  197. #endif    /* THINK_C_1 */
  198.  
  199. /*** other things we need *****/
  200. /*** this is to be include bye THINK_C_1 and THINK_C_2 ***/
  201. #ifdef _Windows
  202. #include <string.h>
  203. #else
  204. #if !defined(ATARI) && !defined (AMIGA_SC_6_1)
  205. extern char *strcpy(),*strcat();
  206.  
  207. #ifdef THINK_C
  208. extern size_t strlen(const char *s);
  209. #else
  210. extern int      strlen();
  211. #endif
  212.  
  213.  
  214. #endif
  215. #endif
  216.  
  217. #if defined(unix) || defined(PIPES)
  218. extern FILE *popen();
  219. #endif
  220.  
  221. /* input data, parsing variables */
  222. extern struct lexical_unit token[];
  223. extern char input_line[];
  224. extern int num_tokens, c_token;
  225. extern TBOOLEAN interactive;    /* from plot.c */
  226.  
  227. extern char replot_line[];
  228. extern struct udvt_entry *first_udv;
  229. extern TBOOLEAN is_3d_plot;
  230.  
  231. extern double magnitude(),real();
  232. extern struct value *const_express();
  233.  
  234. #ifdef _Windows
  235. extern FILE * open_printer();
  236. extern void close_printer();
  237. #endif
  238.  
  239. /******** Local functions ********/
  240. #ifdef THINK_C_1
  241. static void set_xyzlabel();
  242. static void set_label();
  243. static void set_nolabel();
  244. static void set_arrow();
  245. static void set_noarrow();
  246. static void load_tics();
  247. static void load_tic_user();
  248. static void free_marklist();
  249. static void load_tic_series();
  250. static void load_offsets();
  251. #endif
  252.  
  253. #ifdef THINK_C_2
  254. static void show_style(), show_range(), show_zero(), show_border(), show_dgrid3d();
  255. static void show_offsets(), show_output(), show_samples(), show_isosamples();
  256. static void show_view(), show_size(), show_title(), show_xlabel();
  257. static void show_angles(), show_boxwidth();
  258. static void show_ylabel(), show_zlabel(), show_xzeroaxis(), show_yzeroaxis();
  259. static void show_label(), show_arrow(), show_grid(), show_key();
  260. static void show_polar(), show_parametric(), show_tics(), show_ticdef();
  261. static void show_time(), show_term(), show_plot(), show_autoscale(), show_clip();
  262. static void show_contour(), show_mapping(), show_format(), show_logscale();
  263. static void show_variables(), show_surface(), show_hidden3d(), show_label_contours();
  264. #endif
  265.  
  266. #ifdef THINK_C_1
  267. static void delete_label();
  268. static int assign_label_tag();
  269. static void delete_arrow();
  270. static int assign_arrow_tag();
  271. static TBOOLEAN set_one(), set_two(), set_three();
  272. #endif
  273.  
  274. #ifdef THINK_C_2
  275. static TBOOLEAN show_one(), show_two();
  276. #endif
  277.  
  278. #ifdef THINK_C_1
  279. /******** The 'set' command ********/
  280. void
  281. set_command()
  282. {
  283. static char GPFAR setmess[] =
  284.     "valid set options:  'angles' '{no}arrow', {no}autoscale', \n\
  285.     '{no}border', 'boxwidth', '{no}clabel', '{no}clip', 'cntrparam', \n\
  286.         '{no}contour', 'data style', '{no}dgrid3d', 'dummy', 'format', \n\
  287.         'function style', '{no}grid', '{no}hidden3d', 'isosamples', '{no}key', \n\
  288.     '{no}label', '{no}logscale', 'mapping', 'offsets', 'output', \n\
  289.     '{no}parametric', '{no}polar', 'rrange', 'samples', 'size', \n\
  290.     '{no}surface', 'terminal', 'tics', 'ticslevel', '{no}time', 'title', \n\
  291.     'trange', 'urange', 'view', 'vrange', 'xlabel', 'xrange', '{no}xtics', \n\
  292.     'xmtics', 'xdtics', '{no}xzeroaxis', 'ylabel', 'yrange', '{no}ytics', \n\
  293.     'ymtics', 'ydtics', '{no}yzeroaxis', 'zero', '{no}zeroaxis', 'zlabel', \n\
  294.     'zrange', '{no}ztics', 'zmtics', 'zdtics'";
  295.  
  296.     c_token++;
  297.  
  298.     if (!set_one() && !set_two() && !set_three())
  299.     int_error(setmess, c_token);
  300. }
  301. #endif
  302.  
  303. #ifdef THINK_C_1
  304. /* return TRUE if a command match, FALSE if not */
  305. static TBOOLEAN
  306. set_one()
  307. {
  308.     if (almost_equals(c_token,"ar$row")) {
  309.         c_token++;
  310.         set_arrow();
  311.     }
  312.     else if (almost_equals(c_token,"noar$row")) {
  313.         c_token++;
  314.         set_noarrow();
  315.     }
  316.      else if (almost_equals(c_token,"au$toscale")) {
  317.         c_token++;
  318.         if (END_OF_COMMAND) {
  319.            autoscale_r=autoscale_t = autoscale_x = autoscale_y = autoscale_z = TRUE;
  320.         } else if (equals(c_token, "xy") || equals(c_token, "yx")) {
  321.            autoscale_x = autoscale_y = TRUE;
  322.            c_token++;
  323.         } else if (equals(c_token, "r")) {
  324.            autoscale_r = TRUE;
  325.            c_token++;
  326.         } else if (equals(c_token, "t")) {
  327.            autoscale_t = TRUE;
  328.            c_token++;
  329.         } else if (equals(c_token, "x")) {
  330.            autoscale_x = TRUE;
  331.            c_token++;
  332.         } else if (equals(c_token, "y")) {
  333.            autoscale_y = TRUE;
  334.            c_token++;
  335.         } else if (equals(c_token, "z")) {
  336.            autoscale_z = TRUE;
  337.            c_token++;
  338.         }
  339.     } 
  340.     else if (almost_equals(c_token,"noau$toscale")) {
  341.         c_token++;
  342.         if (END_OF_COMMAND) {
  343.            autoscale_r=autoscale_t = autoscale_x = autoscale_y = autoscale_z = FALSE;
  344.         } else if (equals(c_token, "xy") || equals(c_token, "tyx")) {
  345.            autoscale_x = autoscale_y = FALSE;
  346.            c_token++;
  347.         } else if (equals(c_token, "r")) {
  348.            autoscale_r = FALSE;
  349.            c_token++;
  350.         } else if (equals(c_token, "t")) {
  351.            autoscale_t = FALSE;
  352.            c_token++;
  353.         } else if (equals(c_token, "x")) {
  354.            autoscale_x = FALSE;
  355.            c_token++;
  356.         } else if (equals(c_token, "y")) {
  357.            autoscale_y = FALSE;
  358.            c_token++;
  359.         } else if (equals(c_token, "z")) {
  360.            autoscale_z = FALSE;
  361.            c_token++;
  362.         }
  363.     } 
  364.     else if (almost_equals(c_token,"bor$der")) {
  365.         draw_border = TRUE;
  366.         c_token++;
  367.     }
  368.     else if (almost_equals(c_token,"nobor$der")) {
  369.         draw_border = FALSE;
  370.         c_token++;
  371.     }
  372.     else if (almost_equals(c_token,"box$width")) {
  373.         struct value a;
  374.         c_token++;
  375.         if (END_OF_COMMAND)
  376.             boxwidth = -1.0;
  377.         else
  378.             boxwidth = magnitude(const_express(&a));
  379.     }
  380.     else if (almost_equals(c_token,"c$lip")) {
  381.         c_token++;
  382.         if (END_OF_COMMAND)
  383.          /* assuming same as points */
  384.          clip_points = TRUE;
  385.         else if (almost_equals(c_token, "p$oints"))
  386.          clip_points = TRUE;
  387.         else if (almost_equals(c_token, "o$ne"))
  388.          clip_lines1 = TRUE;
  389.         else if (almost_equals(c_token, "t$wo"))
  390.          clip_lines2 = TRUE;
  391.         else
  392.          int_error("expecting 'points', 'one', or 'two'", c_token);
  393.         c_token++;
  394.     }
  395.     else if (almost_equals(c_token,"noc$lip")) {
  396.         c_token++;
  397.         if (END_OF_COMMAND) {
  398.            /* same as all three */
  399.            clip_points = FALSE;
  400.            clip_lines1 = FALSE;
  401.            clip_lines2 = FALSE;
  402.         } else if (almost_equals(c_token, "p$oints"))
  403.          clip_points = FALSE;
  404.         else if (almost_equals(c_token, "o$ne"))
  405.          clip_lines1 = FALSE;
  406.         else if (almost_equals(c_token, "t$wo"))
  407.          clip_lines2 = FALSE;
  408.         else
  409.          int_error("expecting 'points', 'one', or 'two'", c_token);
  410.         c_token++;
  411.     }
  412.     else if (almost_equals(c_token,"hi$dden3d")) {
  413. #ifdef LITE
  414.         printf(" Hidden Line Removal Not Supported in LITE version\n");
  415. #else
  416.         hidden3d = TRUE;
  417. #endif /* LITE */
  418.         c_token++;
  419.     }
  420.     else if (almost_equals(c_token,"nohi$dden3d")) {
  421. #ifdef LITE
  422.         printf(" Hidden Line Removal Not Supported in LITE version\n");
  423. #else
  424.         hidden3d = FALSE;
  425. #endif /* LITE */
  426.         c_token++;
  427.     }
  428.      else if (almost_equals(c_token,"cla$bel")) {
  429.          label_contours = TRUE;
  430.          c_token++;
  431.      }
  432.      else if (almost_equals(c_token,"nocla$bel")) {
  433.          label_contours = FALSE;
  434.          c_token++;
  435.       }
  436.     else if (almost_equals(c_token,"ma$pping3d")) {
  437.         c_token++;
  438.         if (END_OF_COMMAND)
  439.          /* assuming same as points */
  440.          mapping3d = MAP3D_CARTESIAN;
  441.         else if (almost_equals(c_token, "ca$rtesian"))
  442.          mapping3d = MAP3D_CARTESIAN;
  443.         else if (almost_equals(c_token, "s$pherical"))
  444.          mapping3d = MAP3D_SPHERICAL;
  445.         else if (almost_equals(c_token, "cy$lindrical"))
  446.          mapping3d = MAP3D_CYLINDRICAL;
  447.         else
  448.          int_error("expecting 'cartesian', 'spherical', or 'cylindrical'", c_token);
  449.         c_token++;
  450.     }
  451.     else if (almost_equals(c_token,"co$ntour")) {
  452.         c_token++;
  453.         if (END_OF_COMMAND)
  454.          /* assuming same as points */
  455.          draw_contour = CONTOUR_BASE;
  456.         else if (almost_equals(c_token, "ba$se"))
  457.          draw_contour = CONTOUR_BASE;
  458.         else if (almost_equals(c_token, "s$urface"))
  459.          draw_contour = CONTOUR_SRF;
  460.         else if (almost_equals(c_token, "bo$th"))
  461.          draw_contour = CONTOUR_BOTH;
  462.         else
  463.          int_error("expecting 'base', 'surface', or 'both'", c_token);
  464.         c_token++;
  465.     }
  466.     else if (almost_equals(c_token,"noco$ntour")) {
  467.         c_token++;
  468.         draw_contour = CONTOUR_NONE;
  469.     }
  470.     else if (almost_equals(c_token,"cntrp$aram")) {
  471.         struct value a;
  472.  
  473.         c_token++;
  474.         if (END_OF_COMMAND) {
  475.          /* assuming same as defaults */
  476.          contour_pts = 5;
  477.          contour_kind = CONTOUR_KIND_LINEAR;
  478.          contour_order = 4;
  479.          contour_levels = 5;
  480.           levels_kind = LEVELS_AUTO;
  481.         }
  482.         else if (almost_equals(c_token, "p$oints")) {
  483.          c_token++;
  484.          contour_pts = (int) real(const_express(&a));
  485.         }
  486.         else if (almost_equals(c_token, "li$near")) {
  487.          c_token++;
  488.          contour_kind = CONTOUR_KIND_LINEAR;
  489.         }
  490.         else if (almost_equals(c_token, "c$ubicspline")) {
  491.          c_token++;
  492.          contour_kind = CONTOUR_KIND_CUBIC_SPL;
  493.         }
  494.         else if (almost_equals(c_token, "b$spline")) {
  495.          c_token++;
  496.          contour_kind = CONTOUR_KIND_BSPLINE;
  497.         }
  498.  
  499.            else if (almost_equals(c_token, "le$vels")) {
  500.                int i=0;  /* local counter */
  501.                c_token++;
  502.             /*  RKC: I have modified the next two:
  503.              *   to use commas to separate list elements as in xtics
  504.               *   so that incremental lists start,incr[,end]as in "
  505.               */
  506.                if (almost_equals(c_token, "di$screte")) {
  507.                   levels_kind = LEVELS_DISCRETE;
  508.                   c_token++;
  509.                 if(END_OF_COMMAND)
  510.                  int_error("expecting discrete level", c_token);
  511.                 else
  512.                   levels_list[i++] = real(const_express(&a));
  513.                 while(!END_OF_COMMAND){
  514.                   if (!equals(c_token, ","))
  515.                     int_error("expecting comma to separate discrete levels", c_token);
  516.                   c_token++;
  517.                   levels_list[i++] =  real(const_express(&a));
  518.                 }
  519.                   contour_levels = i;
  520.                }
  521.                else if (almost_equals(c_token, "in$cremental")) {
  522.                   levels_kind = LEVELS_INCREMENTAL;
  523.                   c_token++;
  524.                 levels_list[i++] =  real(const_express(&a));
  525.                 if (!equals(c_token, ","))
  526.                   int_error("expecting comma to separate start,incr levels", c_token);
  527.                 c_token++;
  528.                 if((levels_list[i++] = real(const_express(&a)))==0)
  529.                   int_error("increment cannot be 0", c_token);
  530.                  if(!END_OF_COMMAND){
  531.                   if (!equals(c_token, ","))
  532.                     int_error("expecting comma to separate incr,stop levels", c_token);
  533.                   c_token++;
  534.                  contour_levels = (real(const_express(&a))-levels_list[0])/levels_list[1];
  535.                   }
  536.                }
  537.                else if (almost_equals(c_token, "au$to")) {
  538.                    levels_kind = LEVELS_AUTO;
  539.                  c_token++;
  540.                  if(!END_OF_COMMAND)
  541.                      contour_levels = (int) real(const_express(&a));
  542.              }
  543.              else {
  544.               if(levels_kind == LEVELS_DISCRETE)
  545.                 int_error("Levels type is discrete, ignoring new number of contour levels", c_token);
  546.                 contour_levels = (int) real(const_express(&a));
  547.             }
  548.          }
  549.         else if (almost_equals(c_token, "o$rder")) {
  550.          int order;
  551.          c_token++;
  552.          order = (int) real(const_express(&a));
  553.          if ( order < 2 || order > 10 )
  554.              int_error("bspline order must be in [2..10] range.", c_token);
  555.          contour_order = order;
  556.         }
  557.         else
  558.          int_error("expecting 'linear', 'cubicspline', 'bspline', 'points', 'levels' or 'order'", c_token);
  559.         c_token++;
  560.     }
  561.     else if (almost_equals(c_token,"da$ta")) {
  562.         c_token++;
  563.         if (!almost_equals(c_token,"s$tyle"))
  564.             int_error("expecting keyword 'style'",c_token);
  565.         data_style = get_style();
  566.     }
  567.     else if (almost_equals(c_token,"dg$rid3d")) {
  568.         int i;
  569.         TBOOLEAN was_comma = TRUE;
  570.         int local_vals[3];
  571.         struct value a;
  572.  
  573.         local_vals[0] = dgrid3d_row_fineness;
  574.         local_vals[1] = dgrid3d_col_fineness;
  575.         local_vals[2] = dgrid3d_norm_value;
  576.         c_token++;
  577.         for (i = 0; i < 3 && !(END_OF_COMMAND);) {
  578.             if (equals(c_token,",")) {
  579.                 if (was_comma) i++;
  580.                 was_comma = TRUE;
  581.                 c_token++;
  582.             }
  583.             else {
  584.                 if (!was_comma)
  585.                     int_error("',' expected",c_token);
  586.                 local_vals[i] = real(const_express(&a));
  587.                 i++;
  588.                 was_comma = FALSE;
  589.             }
  590.         }
  591.  
  592.  
  593.         if (local_vals[0] < 2 || local_vals[0] > 1000)
  594.             int_error("Row size must be in [2:1000] range; size unchanged",
  595.                   c_token);
  596.         if (local_vals[1] < 2 || local_vals[1] > 1000)
  597.             int_error("Col size must be in [2:1000] range; size unchanged",
  598.                   c_token);
  599.         if (local_vals[2] < 1 || local_vals[2] > 100)
  600.             int_error("Norm must be in [1:100] range; norm unchanged", c_token);
  601.  
  602.         dgrid3d_row_fineness = local_vals[0];
  603.         dgrid3d_col_fineness = local_vals[1];
  604.         dgrid3d_norm_value = local_vals[2];
  605.         dgrid3d = TRUE;
  606.     }
  607.     else if (almost_equals(c_token,"nodg$rid3d")) {
  608.         c_token++;
  609.         dgrid3d = FALSE;
  610.     }
  611.     else if (almost_equals(c_token,"du$mmy")) {
  612.         c_token++;
  613.         if (END_OF_COMMAND)
  614.             int_error("expecting dummy variable name", c_token);
  615.         else {
  616.             if (!equals(c_token,","))
  617.                 copy_str(dummy_var[0],c_token++);
  618.             if (!END_OF_COMMAND && equals(c_token,",")) {
  619.                 c_token++;
  620.                 if (END_OF_COMMAND)
  621.                     int_error("expecting second dummy variable name", c_token);
  622.                 copy_str(dummy_var[1],c_token++);
  623.                 }
  624.         }
  625.     }
  626.     else if (almost_equals(c_token,"fo$rmat")) {
  627.         TBOOLEAN setx, sety, setz;
  628.         c_token++;
  629.         if (equals(c_token,"x")) {
  630.             setx = TRUE; sety = setz = FALSE;
  631.             c_token++;
  632.         }
  633.         else if (equals(c_token,"y")) {
  634.             setx = setz = FALSE; sety = TRUE;
  635.             c_token++;
  636.         }
  637.         else if (equals(c_token,"z")) {
  638.             setx = sety = FALSE; setz = TRUE;
  639.             c_token++;
  640.         }
  641.         else if (equals(c_token,"xy") || equals(c_token,"yx")) {
  642.             setx = sety = TRUE; setz = FALSE;
  643.             c_token++;
  644.         }
  645.         else if (isstring(c_token) || END_OF_COMMAND) {
  646.             /* Assume he wants all */
  647.             setx = sety = setz = TRUE;
  648.         }
  649.         if (END_OF_COMMAND) {
  650.             if (setx)
  651.                 (void) strcpy(xformat,DEF_FORMAT);
  652.             if (sety)
  653.                 (void) strcpy(yformat,DEF_FORMAT);
  654.             if (setz)
  655.                 (void) strcpy(zformat,DEF_FORMAT);
  656.         }
  657.         else {
  658.             if (!isstring(c_token))
  659.               int_error("expecting format string",c_token);
  660.             else {
  661.                 if (setx)
  662.                  quote_str(xformat,c_token);
  663.                 if (sety)
  664.                  quote_str(yformat,c_token);
  665.                 if (setz)
  666.                  quote_str(zformat,c_token);
  667.                 c_token++;
  668.             }
  669.         }
  670.     }
  671.     else if (almost_equals(c_token,"fu$nction")) {
  672.         c_token++;
  673.         if (!almost_equals(c_token,"s$tyle"))
  674.             int_error("expecting keyword 'style'",c_token);
  675.         func_style = get_style();
  676.     }
  677.     else if (almost_equals(c_token,"la$bel")) {
  678.         c_token++;
  679.         set_label();
  680.     }
  681.     else if (almost_equals(c_token,"nola$bel")) {
  682.         c_token++;
  683.         set_nolabel();
  684.     }
  685.     else if (almost_equals(c_token,"lo$gscale")) {
  686.         c_token++;
  687.         if (END_OF_COMMAND) {
  688.         is_log_x = is_log_y = is_log_z = TRUE;
  689.         base_log_x = base_log_y = base_log_z = 10.0;
  690.         log_base_log_x = log_base_log_y = log_base_log_z = log(10.0);
  691.         } else {
  692.         TBOOLEAN change_x = FALSE;
  693.         TBOOLEAN change_y = FALSE;
  694.         TBOOLEAN change_z = FALSE;
  695.         if (chr_in_str(c_token, 'x'))
  696.             change_x = TRUE;
  697.         if (chr_in_str(c_token, 'y'))
  698.             change_y = TRUE;
  699.         if (chr_in_str(c_token, 'z'))
  700.             change_z = TRUE;
  701.         c_token++;
  702.                 if (END_OF_COMMAND) {
  703.             if (change_x) {
  704.             is_log_x = TRUE;
  705.             base_log_x = 10.0;
  706.             log_base_log_x = log(10.0);
  707.             }
  708.             if (change_y) {
  709.             is_log_y = TRUE;
  710.             base_log_y = 10.0;
  711.             log_base_log_y = log(10.0);
  712.             }
  713.             if (change_z) {
  714.             is_log_z = TRUE;
  715.             base_log_z = 10.0;
  716.             log_base_log_z = log(10.0);
  717.             }
  718.         } else {
  719.             struct value a;
  720.             double newbase = magnitude(const_express(&a));
  721.             c_token++;
  722.             if (newbase < 1.1)
  723.             int_error("log base must be >= 1.1; logscale unchanged",
  724.                 c_token);
  725.             else {
  726.             if (change_x) {
  727.                 is_log_x = TRUE;
  728.                 base_log_x = newbase;
  729.                 log_base_log_x = log(newbase);
  730.             }
  731.             if (change_y) {
  732.                 is_log_y = TRUE;
  733.                 base_log_y = newbase;
  734.                 log_base_log_y = log(newbase);
  735.             }
  736.             if (change_z) {
  737.                 is_log_z = TRUE;
  738.                 base_log_z = newbase;
  739.                 log_base_log_z = log(newbase);
  740.             }
  741.             }
  742.         }
  743.         }
  744.     }
  745.     else if (almost_equals(c_token,"nolo$gscale")) {
  746.         c_token++;
  747.         if (END_OF_COMMAND) {
  748.         is_log_x = is_log_y = is_log_z = FALSE;
  749.         } else {
  750.         if (chr_in_str(c_token, 'x')) {
  751.             is_log_x = FALSE;
  752.             base_log_x = 0.0;
  753.             log_base_log_x = 0.0;
  754.                 }
  755.         if (chr_in_str(c_token, 'y')) {
  756.             is_log_y = FALSE;
  757.             base_log_y = 0.0;
  758.             log_base_log_y = 0.0;
  759.                 }
  760.         if (chr_in_str(c_token, 'z')) {
  761.             is_log_z = FALSE;
  762.             base_log_z = 0.0;
  763.             log_base_log_z = 0.0;
  764.                 }
  765.         c_token++;
  766.         }
  767.     } 
  768.     else if (almost_equals(c_token,"of$fsets")) {
  769.         c_token++;
  770.         if (END_OF_COMMAND) {
  771.             loff = roff = toff = boff = 0.0;  /* Reset offsets */
  772.         }
  773.         else {
  774.             load_offsets (&loff,&roff,&toff,&boff);
  775.         }
  776.     }
  777.     else
  778.         return(FALSE);    /* no command match */
  779.     return(TRUE);
  780. }
  781. #endif
  782.  
  783. #ifdef THINK_C_1
  784. /* return TRUE if a command match, FALSE if not */
  785. static TBOOLEAN
  786. set_two()
  787. {
  788.      char testfile[MAX_LINE_LEN+1];
  789. #if defined(unix) || defined(PIPES)
  790.      static TBOOLEAN pipe_open = FALSE;
  791. #endif /* unix || PIPES */
  792.  
  793.     if (almost_equals(c_token,"o$utput")) {
  794.         register FILE *f;
  795.  
  796.         c_token++;
  797.         if (term && term_init)
  798.             (*term_tbl[term].reset)();
  799.         if (END_OF_COMMAND) {    /* no file specified */
  800.              UP_redirect (4);
  801.             if (outfile != stdout) { /* Never close stdout */
  802. #if defined(unix) || defined(PIPES)
  803.                 if ( pipe_open ) {
  804.                     (void) pclose(outfile);
  805.                     pipe_open = FALSE;
  806.                 } else
  807. #endif /* unix || PIPES */
  808. #ifdef _Windows
  809.                   if ( !stricmp(outstr,"'PRN'") )
  810.                     close_printer();
  811.                   else
  812. #endif
  813.                     (void) fclose(outfile);
  814.             }
  815.             outfile = stdout; /* Don't dup... */
  816.             term_init = FALSE;
  817.             (void) strcpy(outstr,"STDOUT");
  818.         } else if (!isstring(c_token))
  819. #ifdef THINK_C
  820.             {     Point where={97,103};
  821.                 SFReply reply;
  822.                 
  823.                 SFPutFile(where,NULL, "\pUntitled",NULL, &reply);
  824.                 if( (reply.good) && (SetVol(reply.fName,reply.vRefNum) == noErr)){
  825.                     PtoCstr((char *) reply.fName);
  826.                     strcpy(testfile,(char *) reply.fName);
  827.                     if ((f = fopen(testfile,"w")) == (FILE *)NULL) {
  828.                       os_error("cannot open file; output not changed",c_token);
  829.                     }
  830.                     if (outfile != stdout) /* Never close stdout */
  831.                         (void) fclose(outfile);
  832.                     outfile = f;
  833.                     term_init = FALSE;
  834.                     outstr[0] = '\'';
  835.                     (void) strcat(strcpy(outstr+1,testfile),"'");
  836.                      UP_redirect (1);
  837.                 }
  838.                 else{
  839.                     int_error("expecting filename",c_token);
  840.                 }
  841.             }
  842. #else
  843.             int_error("expecting filename",c_token);
  844. #endif
  845.         else {
  846.             quote_str(testfile,c_token);
  847. #if defined(unix) || defined(PIPES)
  848.             if ( *testfile == '|' ) {
  849.               if ((f = popen(testfile+1,"w")) == (FILE *)NULL)
  850.                 os_error("cannot create pipe; output not changed",c_token);
  851.               else
  852.                 pipe_open = TRUE;
  853.             } else
  854. #endif /* unix || PIPES */
  855. #ifdef _Windows
  856.             if ( !stricmp(outstr,"'PRN'") ) {
  857.                 /* we can't call open_printer() while printer is open, so */
  858.                 close_printer();    /* close printer immediately if open */
  859.                 outfile = stdout;    /* and reset output to stdout */
  860.                 term_init = FALSE;
  861.                 (void) strcpy(outstr,"STDOUT");
  862.             }
  863.             if ( !stricmp(testfile,"PRN") ) {
  864.               if ((f = open_printer()) == (FILE *)NULL)
  865.                 os_error("cannot open printer temporary file; output may have changed",c_token);
  866.             } else
  867. #endif
  868.               if ((f = fopen(testfile,"w")) == (FILE *)NULL)
  869.                 os_error("cannot open file; output not changed",c_token);
  870.             if (outfile != stdout) /* Never close stdout */
  871. #if defined(unix) || defined(PIPES)
  872.                 if( pipe_open ) {
  873.                 (void) pclose(outfile);
  874.                 pipe_open=FALSE;
  875.                 } else
  876. #endif /* unix || PIPES */
  877.                 (void) fclose(outfile);
  878.             outfile = f;
  879.             term_init = FALSE;
  880.             outstr[0] = '\'';
  881.             (void) strcat(strcpy(outstr+1,testfile),"'");
  882.              UP_redirect (1);
  883.         }
  884.         c_token++;
  885.     }
  886.     else if (almost_equals(c_token,"tit$le")) {
  887.         set_xyzlabel(title,&title_xoffset,&title_yoffset);
  888.     }
  889.     else if (almost_equals(c_token,"xl$abel")) {
  890.         set_xyzlabel(xlabel,&xlabel_xoffset,&xlabel_yoffset);
  891.     }
  892.     else if (almost_equals(c_token,"yl$abel")) {
  893.         set_xyzlabel(ylabel,&ylabel_xoffset,&ylabel_yoffset);
  894.     }
  895.     else if (almost_equals(c_token,"zl$abel")) {
  896.         set_xyzlabel(zlabel,&zlabel_xoffset,&zlabel_yoffset);
  897.     }
  898.     else if (almost_equals(c_token,"xzero$axis")) {
  899.         c_token++;
  900.         xzeroaxis = TRUE;
  901.     } 
  902.     else if (almost_equals(c_token,"yzero$axis")) {
  903.         c_token++;
  904.         yzeroaxis = TRUE;
  905.     } 
  906.     else if (almost_equals(c_token,"zeroa$xis")) {
  907.         c_token++;
  908.         yzeroaxis = TRUE;
  909.         xzeroaxis = TRUE;
  910.     } 
  911.     else if (almost_equals(c_token,"noxzero$axis")) {
  912.         c_token++;
  913.         xzeroaxis = FALSE;
  914.     } 
  915.     else if (almost_equals(c_token,"noyzero$axis")) {
  916.         c_token++;
  917.         yzeroaxis = FALSE;
  918.     } 
  919.     else if (almost_equals(c_token,"nozero$axis")) {
  920.         c_token++;
  921.         xzeroaxis = FALSE;
  922.         yzeroaxis = FALSE;
  923.     } 
  924.     else if (almost_equals(c_token,"par$ametric")) {
  925.         if (!parametric) {
  926.            parametric = TRUE;
  927.            strcpy (dummy_var[0], "t");
  928.            strcpy (dummy_var[1], "y");
  929.            if (interactive)
  930.              (void) fprintf(stderr,"\n\tdummy variable is t for curves, u/v for surfaces\n");
  931.         }
  932.         c_token++;
  933.     }
  934.     else if (almost_equals(c_token,"nopar$ametric")) {
  935.         if (parametric) {
  936.            parametric = FALSE;
  937.            strcpy (dummy_var[0], "x");
  938.            strcpy (dummy_var[1], "y");
  939.            if (interactive)
  940.              (void) fprintf(stderr,"\n\tdummy variable is x for curves, x/y for surfaces\n");
  941.         }
  942.         c_token++;
  943.     }
  944.     else if (almost_equals(c_token,"pol$ar")) {
  945.         if (!polar) {
  946.             polar = TRUE;
  947.             if (parametric) {
  948.                 tmin = 0.0;
  949.                 tmax = 2*Pi;
  950.             } else if (angles_format == ANGLES_DEGREES) {
  951.                 xmin = 0.0;
  952.                 xmax = 360.0;
  953.             } else {
  954.                 xmin = 0.0;
  955.                 xmax = 2*Pi;
  956.             }
  957.         }
  958.         c_token++;
  959.     }
  960.     else if (almost_equals(c_token,"nopo$lar")) {
  961.         if (polar) {
  962.             polar = FALSE;
  963.             if (parametric) {
  964.                 tmin = -5.0;
  965.                 tmax = 5.0;
  966.             } else {
  967.                 xmin = -10.0;
  968.                 xmax = 10.0;
  969.             }
  970.         }
  971.         c_token++;
  972.     }
  973.     else if (almost_equals(c_token,"an$gles")) {
  974.         c_token++;
  975.         if (END_OF_COMMAND) {
  976.         /* assuming same as defaults */
  977.         angles_format = ANGLES_RADIANS;
  978.         }
  979.         else if (almost_equals(c_token, "r$adians")) {
  980.         angles_format = ANGLES_RADIANS;
  981.         c_token++;
  982.         }
  983.         else if (almost_equals(c_token, "d$egrees")) {
  984.         angles_format = ANGLES_DEGREES;
  985.         c_token++;
  986.         }
  987.         else
  988.          int_error("expecting 'radians' or 'degrees'", c_token);
  989.     }
  990.     else if (almost_equals(c_token,"g$rid")) {
  991.         grid = TRUE;
  992.         c_token++;
  993.     }
  994.     else if (almost_equals(c_token,"nog$rid")) {
  995.         grid = FALSE;
  996.         c_token++;
  997.     }
  998.     else if (almost_equals(c_token,"su$rface")) {
  999.         draw_surface = TRUE;
  1000.         c_token++;
  1001.     }
  1002.     else if (almost_equals(c_token,"nosu$rface")) {
  1003.         draw_surface = FALSE;
  1004.         c_token++;
  1005.     }
  1006.     else if (almost_equals(c_token,"k$ey")) {
  1007.         struct value a;
  1008.         c_token++;
  1009.         if (END_OF_COMMAND) {
  1010.             key = -1;
  1011.         } 
  1012.         else {
  1013.             key_x = real(const_express(&a));
  1014.             if (!equals(c_token,","))
  1015.                 int_error("',' expected",c_token);
  1016.             c_token++;
  1017.             key_y = real(const_express(&a));
  1018.             if (equals(c_token,","))
  1019.             {
  1020.                     c_token++;
  1021.                 key_z = real(const_express(&a));
  1022.             }
  1023.             key = 1;
  1024.         } 
  1025.     }
  1026.     else if (almost_equals(c_token,"nok$ey")) {
  1027.         key = 0;
  1028.         c_token++;
  1029.     }
  1030.     else if (almost_equals(c_token,"tic$s")) {
  1031.         tic_in = TRUE;
  1032.         c_token++;
  1033.         if (almost_equals(c_token,"i$n")) {
  1034.             tic_in = TRUE;
  1035.             c_token++;
  1036.         }
  1037.         else if (almost_equals(c_token,"o$ut")) {
  1038.             tic_in = FALSE;
  1039.             c_token++;
  1040.         }
  1041.     }
  1042.      else if (almost_equals(c_token,"xmt$ics")) {
  1043.      xtics = TRUE;
  1044.      c_token++;
  1045.      if(xticdef.type == TIC_USER){
  1046.          free_marklist(xticdef.def.user);
  1047.          xticdef.def.user = NULL;
  1048.      }
  1049.     xticdef.type = TIC_MONTH;
  1050.      }
  1051.      else if (almost_equals(c_token,"xdt$ics")) {
  1052.      xtics = TRUE;
  1053.      c_token++;
  1054.      if(xticdef.type == TIC_USER){
  1055.          free_marklist(xticdef.def.user);
  1056.          xticdef.def.user = NULL;
  1057.      }
  1058.     xticdef.type = TIC_DAY;
  1059.      }
  1060.      else if (almost_equals(c_token,"xt$ics")) {
  1061.         xtics = TRUE;
  1062.         c_token++;
  1063.         if (END_OF_COMMAND) { /* reset to default */
  1064.            if (xticdef.type == TIC_USER) {
  1065.               free_marklist(xticdef.def.user);
  1066.               xticdef.def.user = NULL;
  1067.            }
  1068.            xticdef.type = TIC_COMPUTED;
  1069.         }
  1070.         else
  1071.          load_tics(&xticdef);
  1072.     } 
  1073.      else if (almost_equals(c_token,"noxt$ics")) {
  1074.         xtics = FALSE;
  1075.         c_token++;
  1076.     } 
  1077.      else if (almost_equals(c_token,"ymt$ics")) {
  1078.      ytics = TRUE;
  1079.      c_token++;
  1080.      if(yticdef.type == TIC_USER){
  1081.          free_marklist(yticdef.def.user);
  1082.          yticdef.def.user = NULL;
  1083.      }
  1084.     yticdef.type = TIC_MONTH;
  1085.      }
  1086.      else if (almost_equals(c_token,"ydt$ics")) {
  1087.      ytics = TRUE;
  1088.      c_token++;
  1089.      if(yticdef.type == TIC_USER){
  1090.          free_marklist(yticdef.def.user);
  1091.          yticdef.def.user = NULL;
  1092.      }
  1093.     yticdef.type = TIC_DAY;
  1094.      }
  1095.      else if (almost_equals(c_token,"yt$ics")) {
  1096.         ytics = TRUE;
  1097.         c_token++;
  1098.         if (END_OF_COMMAND) { /* reset to default */
  1099.            if (yticdef.type == TIC_USER) {
  1100.               free_marklist(yticdef.def.user);
  1101.               yticdef.def.user = NULL;
  1102.            }
  1103.            yticdef.type = TIC_COMPUTED;
  1104.         }
  1105.         else
  1106.          load_tics(&yticdef);
  1107.     } 
  1108.      else if (almost_equals(c_token,"noyt$ics")) {
  1109.         ytics = FALSE;
  1110.         c_token++;
  1111.     } 
  1112.      else if (almost_equals(c_token,"zmt$ics")) {
  1113.      ztics = TRUE;
  1114.      c_token++;
  1115.      if(zticdef.type == TIC_USER){
  1116.          free_marklist(zticdef.def.user);
  1117.          zticdef.def.user = NULL;
  1118.      }
  1119.     zticdef.type = TIC_MONTH;
  1120.      }
  1121.      else if (almost_equals(c_token,"zdt$ics")) {
  1122.      ztics = TRUE;
  1123.      c_token++;
  1124.      if(zticdef.type == TIC_USER){
  1125.          free_marklist(zticdef.def.user);
  1126.          zticdef.def.user = NULL;
  1127.      }
  1128.     zticdef.type = TIC_DAY;
  1129.      }
  1130.      else if (almost_equals(c_token,"zt$ics")) {
  1131.         ztics = TRUE;
  1132.         c_token++;
  1133.         if (END_OF_COMMAND) { /* reset to default */
  1134.            if (zticdef.type == TIC_USER) {
  1135.               free_marklist(zticdef.def.user);
  1136.               zticdef.def.user = NULL;
  1137.            }
  1138.            zticdef.type = TIC_COMPUTED;
  1139.         }
  1140.         else
  1141.          load_tics(&zticdef);
  1142.     } 
  1143.      else if (almost_equals(c_token,"nozt$ics")) {
  1144.         ztics = FALSE;
  1145.         c_token++;
  1146.     } 
  1147.     else if (almost_equals(c_token,"ticsl$evel")) {
  1148.         double tlvl;
  1149.         struct value a;
  1150.  
  1151.         c_token++;
  1152.         tlvl = real(const_express(&a));
  1153.         if (tlvl < 0.0)
  1154.             int_error("tics level must be > 0; ticslevel unchanged",
  1155.                 c_token);
  1156.         else {
  1157.             ticslevel = tlvl;
  1158.         }
  1159.     }
  1160.     else
  1161.     return(FALSE);    /* no command match */
  1162.  
  1163.     return(TRUE);
  1164. }
  1165. #endif
  1166.  
  1167. #ifdef THINK_C_1
  1168. /* return TRUE if a command match, FALSE if not */
  1169. static TBOOLEAN
  1170. set_three()
  1171. {
  1172.      if (almost_equals(c_token,"sa$mples")) {
  1173.         register int tsamp1, tsamp2;
  1174.         struct value a;
  1175.  
  1176.         c_token++;
  1177.         tsamp1 = (int)magnitude(const_express(&a));
  1178.         tsamp2 = tsamp1;
  1179.         if (!END_OF_COMMAND) {
  1180.             if (!equals(c_token,","))
  1181.                 int_error("',' expected",c_token);
  1182.             c_token++;
  1183.             tsamp2 = (int)magnitude(const_express(&a));
  1184.         }
  1185.         if (tsamp1 < 2 || tsamp2 < 2)
  1186.             int_error("sampling rate must be > 1; sampling unchanged",
  1187.                 c_token);
  1188.         else {
  1189.                 extern struct surface_points *first_3dplot;
  1190.             register struct surface_points *f_3dp = first_3dplot;
  1191.  
  1192.             first_3dplot = NULL;
  1193.             sp_free(f_3dp);
  1194.  
  1195.             samples = tsamp1;
  1196.             samples_1 = tsamp1;
  1197.             samples_2 = tsamp2;
  1198.         }
  1199.     }
  1200.     else if (almost_equals(c_token,"isosa$mples")) {
  1201.         register int tsamp1, tsamp2;
  1202.         struct value a;
  1203.  
  1204.         c_token++;
  1205.         tsamp1 = (int)magnitude(const_express(&a));
  1206.         tsamp2 = tsamp1;
  1207.         if (!END_OF_COMMAND) {
  1208.             if (!equals(c_token,","))
  1209.                 int_error("',' expected",c_token);
  1210.             c_token++;
  1211.             tsamp2 = (int)magnitude(const_express(&a));
  1212.         }
  1213.         if (tsamp1 < 2 || tsamp2 < 2)
  1214.             int_error("sampling rate must be > 1; sampling unchanged",
  1215.                 c_token);
  1216.         else {
  1217.                 extern struct curve_points *first_plot;
  1218.                 extern struct surface_points *first_3dplot;
  1219.             register struct curve_points *f_p = first_plot;
  1220.             register struct surface_points *f_3dp = first_3dplot;
  1221.  
  1222.             first_plot = NULL;
  1223.             first_3dplot = NULL;
  1224.             cp_free(f_p);
  1225.             sp_free(f_3dp);
  1226.  
  1227.             iso_samples_1 = tsamp1;
  1228.             iso_samples_2 = tsamp2;
  1229.         }
  1230.     }
  1231.     else if (almost_equals(c_token,"si$ze")) {
  1232.         struct value s;
  1233.         c_token++;
  1234.         if (END_OF_COMMAND) {
  1235.             xsize = 1.0;
  1236.             ysize = 1.0;
  1237.         } 
  1238.         else {
  1239.                 xsize=real(const_express(&s));
  1240.                 if (!equals(c_token,","))
  1241.                     int_error("',' expected",c_token);
  1242.                 c_token++;
  1243.                 ysize=real(const_express(&s));
  1244.         } 
  1245.     } 
  1246.     else if (almost_equals(c_token,"t$erminal")) {
  1247.         c_token++;
  1248.         if (END_OF_COMMAND) {
  1249.             list_terms();
  1250.             screen_ok = FALSE;
  1251.         }
  1252.         else {
  1253.             if (term && term_init) {
  1254.                 (*term_tbl[term].reset)();
  1255.                 (void) fflush(outfile);
  1256.             }
  1257.             term = set_term(c_token);
  1258.             c_token++;
  1259.  
  1260.             /* get optional mode parameters */
  1261.             if (term)
  1262.                 (*term_tbl[term].options)();
  1263.             if (interactive && *term_options)
  1264.                 fprintf(stderr,"Options are '%s'\n",term_options);
  1265.         }
  1266.     }
  1267.     else if (almost_equals(c_token,"tim$e")) {
  1268.         timedate = TRUE;
  1269.         c_token++;
  1270.         if (!END_OF_COMMAND) {
  1271.             struct value a;
  1272.  
  1273.             /* We have x,y offsets specified */
  1274.             if (!equals(c_token,","))
  1275.                 time_xoffset = (int)real(const_express(&a));
  1276.             if (!END_OF_COMMAND && equals(c_token,",")) {
  1277.                 c_token++;
  1278.                 time_yoffset = (int)real(const_express(&a));
  1279.             }
  1280.         }
  1281.     }
  1282.     else if (almost_equals(c_token,"not$ime")) {
  1283.         timedate = FALSE;
  1284.         c_token++;
  1285.     }
  1286.     else if (almost_equals(c_token,"rr$ange")) {
  1287.          TBOOLEAN changed;
  1288.         c_token++;
  1289.         if (!equals(c_token,"["))
  1290.             int_error("expecting '['",c_token);
  1291.         c_token++;
  1292.         changed = load_range(&rmin,&rmax);
  1293.         if (!equals(c_token,"]"))
  1294.           int_error("expecting ']'",c_token);
  1295.         c_token++;
  1296.         if (changed)
  1297.           autoscale_r = FALSE;
  1298.     }
  1299.     else if (almost_equals(c_token,"tr$ange")) {
  1300.          TBOOLEAN changed;
  1301.         c_token++;
  1302.         if (!equals(c_token,"["))
  1303.             int_error("expecting '['",c_token);
  1304.         c_token++;
  1305.         changed = load_range(&tmin,&tmax);
  1306.         if (!equals(c_token,"]"))
  1307.           int_error("expecting ']'",c_token);
  1308.         c_token++;
  1309.         if (changed)
  1310.           autoscale_t = FALSE;
  1311.     }
  1312.     else if (almost_equals(c_token,"ur$ange")) {
  1313.          TBOOLEAN changed;
  1314.         c_token++;
  1315.         if (!equals(c_token,"["))
  1316.             int_error("expecting '['",c_token);
  1317.         c_token++;
  1318.         changed = load_range(&umin,&umax);
  1319.         if (!equals(c_token,"]"))
  1320.           int_error("expecting ']'",c_token);
  1321.         c_token++;
  1322.         if (changed)
  1323.           autoscale_u = FALSE;
  1324.     }
  1325.     else if (almost_equals(c_token,"vi$ew")) {
  1326.         int i;
  1327.         TBOOLEAN was_comma = TRUE;
  1328.         double local_vals[4];
  1329.         struct value a;
  1330.  
  1331.         local_vals[0] = surface_rot_x;
  1332.         local_vals[1] = surface_rot_z;
  1333.         local_vals[2] = surface_scale;
  1334.         local_vals[3] = surface_zscale;
  1335.         c_token++;
  1336.         for (i = 0; i < 4 && !(END_OF_COMMAND);) {
  1337.             if (equals(c_token,",")) {
  1338.                 if (was_comma) i++;
  1339.                 was_comma = TRUE;
  1340.                 c_token++;
  1341.             }
  1342.             else {
  1343.                 if (!was_comma)
  1344.                     int_error("',' expected",c_token);
  1345.                 local_vals[i] = real(const_express(&a));
  1346.                 i++;
  1347.                 was_comma = FALSE;
  1348.             }
  1349.         }
  1350.  
  1351.         if (local_vals[0] < 0 || local_vals[0] > 180)
  1352.             int_error("rot_x must be in [0:180] degrees range; view unchanged",
  1353.                   c_token);
  1354.         if (local_vals[1] < 0 || local_vals[1] > 360)
  1355.             int_error("rot_z must be in [0:360] degrees range; view unchanged",
  1356.                   c_token);
  1357.         if (local_vals[2] < 1e-6)
  1358.             int_error("scale must be > 0; view unchanged", c_token);
  1359.         if (local_vals[3] < 1e-6)
  1360.             int_error("zscale must be > 0; view unchanged", c_token);
  1361.  
  1362.         surface_rot_x = local_vals[0];
  1363.         surface_rot_z = local_vals[1];
  1364.         surface_scale = local_vals[2];
  1365.         surface_zscale = local_vals[3];
  1366.     }
  1367.     else if (almost_equals(c_token,"vr$ange")) {
  1368.          TBOOLEAN changed;
  1369.         c_token++;
  1370.         if (!equals(c_token,"["))
  1371.             int_error("expecting '['",c_token);
  1372.         c_token++;
  1373.         changed = load_range(&vmin,&vmax);
  1374.         if (!equals(c_token,"]"))
  1375.           int_error("expecting ']'",c_token);
  1376.         c_token++;
  1377.         if (changed)
  1378.           autoscale_v = FALSE;
  1379.     }
  1380.     else if (almost_equals(c_token,"xr$ange")) {
  1381.          TBOOLEAN changed;
  1382.         c_token++;
  1383.         if (!equals(c_token,"["))
  1384.             int_error("expecting '['",c_token);
  1385.         c_token++;
  1386.         changed = load_range(&xmin,&xmax);
  1387.         if (!equals(c_token,"]"))
  1388.           int_error("expecting ']'",c_token);
  1389.         c_token++;
  1390.         if (changed)
  1391.           autoscale_x = FALSE;
  1392.     }
  1393.     else if (almost_equals(c_token,"yr$ange")) {
  1394.          TBOOLEAN changed;
  1395.         c_token++;
  1396.         if (!equals(c_token,"["))
  1397.             int_error("expecting '['",c_token);
  1398.         c_token++;
  1399.         changed = load_range(&ymin,&ymax);
  1400.         if (!equals(c_token,"]"))
  1401.           int_error("expecting ']'",c_token);
  1402.         c_token++;
  1403.         if (changed)
  1404.           autoscale_y = FALSE;
  1405.     }
  1406.     else if (almost_equals(c_token,"zr$ange")) {
  1407.          TBOOLEAN changed;
  1408.         c_token++;
  1409.         if (!equals(c_token,"["))
  1410.             int_error("expecting '['",c_token);
  1411.         c_token++;
  1412.         changed = load_range(&zmin,&zmax);
  1413.         if (!equals(c_token,"]"))
  1414.           int_error("expecting ']'",c_token);
  1415.         c_token++;
  1416.         if (changed)
  1417.           autoscale_z = FALSE;
  1418.     }
  1419.     else if (almost_equals(c_token,"z$ero")) {
  1420.         struct value a;
  1421.         c_token++;
  1422.         zero = magnitude(const_express(&a));
  1423.     }
  1424.     else
  1425.         return(FALSE);    /* no command match */
  1426.     return(TRUE);
  1427. }
  1428. #endif
  1429.  
  1430. #ifdef THINK_C_1
  1431. /*********** Support functions for set_command ***********/
  1432.  
  1433. /* process a 'set {x/y/z}label command */
  1434. /* set {x/y/z}label {label_text} {x}{,y} */
  1435. static void set_xyzlabel(str,xpos,ypos)
  1436. char *str;
  1437. int *xpos,*ypos;
  1438. {
  1439.     c_token++;
  1440.     if (END_OF_COMMAND) {    /* no label specified */
  1441.         str[0] = '\0';
  1442.     } else {
  1443.         if (isstring(c_token)) {
  1444.             /* We have string specified - grab it. */
  1445.             quotel_str(str,c_token);
  1446.             c_token++;
  1447.         }
  1448.         if (!END_OF_COMMAND) {
  1449.             struct value a;
  1450.  
  1451.             /* We have x,y offsets specified */
  1452.             if (!equals(c_token,","))
  1453.                 *xpos = (int)real(const_express(&a));
  1454.             if (!END_OF_COMMAND && equals(c_token,",")) {
  1455.                 c_token++;
  1456.                 *ypos = (int)real(const_express(&a));
  1457.             }
  1458.         }
  1459.     }
  1460. }
  1461. #endif
  1462.  
  1463. #ifdef THINK_C_1
  1464. /* process a 'set label' command */
  1465. /* set label {tag} {label_text} {at x,y} {pos} */
  1466. static void
  1467. set_label()
  1468. {
  1469.     struct value a;
  1470.     struct text_label *this_label = NULL;
  1471.     struct text_label *new_label = NULL;
  1472.     struct text_label *prev_label = NULL;
  1473.     double x, y, z;
  1474.     char text[MAX_LINE_LEN+1];
  1475.     enum JUSTIFY just;
  1476.     int tag;
  1477.     TBOOLEAN set_text, set_position, set_just;
  1478.  
  1479.     /* get tag */
  1480.     if (!END_OF_COMMAND 
  1481.        && !isstring(c_token) 
  1482.        && !equals(c_token, "at")
  1483.        && !equals(c_token, "left")
  1484.        && !equals(c_token, "center")
  1485.        && !equals(c_token, "centre")
  1486.        && !equals(c_token, "right")) {
  1487.        /* must be a tag expression! */
  1488.        tag = (int)real(const_express(&a));
  1489.        if (tag <= 0)
  1490.         int_error("tag must be > zero", c_token);
  1491.     } else
  1492.      tag = assign_label_tag(); /* default next tag */
  1493.      
  1494.     /* get text */
  1495.     if (!END_OF_COMMAND && isstring(c_token)) {
  1496.        /* get text */
  1497.        quotel_str(text, c_token);
  1498.        c_token++;
  1499.        set_text = TRUE;
  1500.     } else {
  1501.        text[0] = '\0';        /* default no text */
  1502.        set_text = FALSE;
  1503.     }
  1504.      
  1505.     /* get justification - what the heck, let him put it here */
  1506.     if (!END_OF_COMMAND && !equals(c_token, "at")) {
  1507.        if (almost_equals(c_token,"l$eft")) {
  1508.           just = LEFT;
  1509.        }
  1510.        else if (almost_equals(c_token,"c$entre")
  1511.               || almost_equals(c_token,"c$enter")) {
  1512.           just = CENTRE;
  1513.        }
  1514.        else if (almost_equals(c_token,"r$ight")) {
  1515.           just = RIGHT;
  1516.        }
  1517.        else
  1518.         int_error("bad syntax in set label", c_token);
  1519.        c_token++;
  1520.        set_just = TRUE;
  1521.     } else {
  1522.        just = LEFT;            /* default left justified */
  1523.        set_just = FALSE;
  1524.     } 
  1525.  
  1526.     /* get position */
  1527.     if (!END_OF_COMMAND && equals(c_token, "at")) {
  1528.        c_token++;
  1529.        if (END_OF_COMMAND)
  1530.         int_error("coordinates expected", c_token);
  1531.        /* get coordinates */
  1532.        x = real(const_express(&a));
  1533.        if (!equals(c_token,","))
  1534.         int_error("',' expected",c_token);
  1535.        c_token++;
  1536.        y = real(const_express(&a));
  1537.        if (equals(c_token,",")) {
  1538.         c_token++;
  1539.         z = real(const_express(&a));
  1540.        }
  1541.        else
  1542.             z = 0;
  1543.        set_position = TRUE;
  1544.     } else {
  1545.        x = y = z = 0;            /* default at origin */
  1546.        set_position = FALSE;
  1547.     }
  1548.  
  1549.     /* get justification */
  1550.     if (!END_OF_COMMAND) {
  1551.        if (set_just)
  1552.         int_error("only one justification is allowed", c_token);
  1553.        if (almost_equals(c_token,"l$eft")) {
  1554.           just = LEFT;
  1555.        }
  1556.        else if (almost_equals(c_token,"c$entre")
  1557.               || almost_equals(c_token,"c$enter")) {
  1558.           just = CENTRE;
  1559.        }
  1560.        else if (almost_equals(c_token,"r$ight")) {
  1561.           just = RIGHT;
  1562.        }
  1563.        else
  1564.         int_error("bad syntax in set label", c_token);
  1565.        c_token++;
  1566.        set_just = TRUE;
  1567.     } 
  1568.  
  1569.     if (!END_OF_COMMAND)
  1570.      int_error("extraenous or out-of-order arguments in set label", c_token);
  1571.  
  1572.     /* OK! add label */
  1573.     if (first_label != NULL) { /* skip to last label */
  1574.        for (this_label = first_label; this_label != NULL ; 
  1575.            prev_label = this_label, this_label = this_label->next)
  1576.         /* is this the label we want? */
  1577.         if (tag <= this_label->tag)
  1578.           break;
  1579.     }
  1580.     if (this_label != NULL && tag == this_label->tag) {
  1581.        /* changing the label */
  1582.        if (set_position) {
  1583.           this_label->x = x;
  1584.           this_label->y = y;
  1585.           this_label->z = z;
  1586.        }
  1587.        if (set_text)
  1588.         (void) strcpy(this_label->text, text);
  1589.        if (set_just)
  1590.         this_label->pos = just;
  1591.     } else {
  1592.        /* adding the label */
  1593.        new_label = (struct text_label *) 
  1594.         alloc ( (unsigned long) sizeof(struct text_label), "label");
  1595.        if (prev_label != NULL)
  1596.         prev_label->next = new_label; /* add it to end of list */
  1597.        else 
  1598.         first_label = new_label; /* make it start of list */
  1599.        new_label->tag = tag;
  1600.        new_label->next = this_label;
  1601.        new_label->x = x;
  1602.        new_label->y = y;
  1603.        new_label->z = z;
  1604.        (void) strcpy(new_label->text, text);
  1605.        new_label->pos = just;
  1606.     }
  1607. }
  1608. #endif
  1609.  
  1610. #ifdef THINK_C_1
  1611. /* process 'set nolabel' command */
  1612. /* set nolabel {tag} */
  1613. static void
  1614. set_nolabel()
  1615. {
  1616.     struct value a;
  1617.     struct text_label *this_label;
  1618.     struct text_label *prev_label; 
  1619.     int tag;
  1620.  
  1621.     if (END_OF_COMMAND) {
  1622.        /* delete all labels */
  1623.        while (first_label != NULL)
  1624.         delete_label((struct text_label *)NULL,first_label);
  1625.     }
  1626.     else {
  1627.        /* get tag */
  1628.        tag = (int)real(const_express(&a));
  1629.        if (!END_OF_COMMAND)
  1630.         int_error("extraneous arguments to set nolabel", c_token);
  1631.        for (this_label = first_label, prev_label = NULL;
  1632.            this_label != NULL;
  1633.            prev_label = this_label, this_label = this_label->next) {
  1634.           if (this_label->tag == tag) {
  1635.              delete_label(prev_label,this_label);
  1636.              return;        /* exit, our job is done */
  1637.           }
  1638.        }
  1639.        int_error("label not found", c_token);
  1640.     }
  1641. }
  1642. #endif
  1643.  
  1644. #ifdef THINK_C_1
  1645. /* assign a new label tag */
  1646. /* labels are kept sorted by tag number, so this is easy */
  1647. static int                /* the lowest unassigned tag number */
  1648. assign_label_tag()
  1649. {
  1650.     struct text_label *this_label;
  1651.     int last = 0;            /* previous tag value */
  1652.  
  1653.     for (this_label = first_label; this_label != NULL;
  1654.         this_label = this_label->next)
  1655.      if (this_label->tag == last+1)
  1656.        last++;
  1657.      else
  1658.        break;
  1659.     
  1660.     return (last+1);
  1661. }
  1662. #endif
  1663.  
  1664. #ifdef THINK_C_1
  1665. /* delete label from linked list started by first_label.
  1666.  * called with pointers to the previous label (prev) and the 
  1667.  * label to delete (this).
  1668.  * If there is no previous label (the label to delete is
  1669.  * first_label) then call with prev = NULL.
  1670.  */
  1671. static void
  1672. delete_label(prev,this)
  1673.     struct text_label *prev, *this;
  1674. {
  1675.     if (this!=NULL)    {        /* there really is something to delete */
  1676.        if (prev!=NULL)        /* there is a previous label */
  1677.         prev->next = this->next; 
  1678.        else                /* this = first_label so change first_label */
  1679.         first_label = this->next;
  1680.        free((char *)this);
  1681.     }
  1682. }
  1683. #endif
  1684.  
  1685. #ifdef THINK_C_1
  1686. /* process a 'set arrow' command */
  1687. /* set arrow {tag} {from x,y} {to x,y} {{no}head} */
  1688. static void
  1689. set_arrow()
  1690. {
  1691.     struct value a;
  1692.     struct arrow_def *this_arrow = NULL;
  1693.     struct arrow_def *new_arrow = NULL;
  1694.     struct arrow_def *prev_arrow = NULL;
  1695.     double sx, sy, sz;
  1696.     double ex, ey, ez;
  1697.     int tag;
  1698.     TBOOLEAN set_start, set_end, head = 1;
  1699.  
  1700.     /* get tag */
  1701.     if (!END_OF_COMMAND 
  1702.        && !equals(c_token, "from")
  1703.        && !equals(c_token, "to")) {
  1704.        /* must be a tag expression! */
  1705.        tag = (int)real(const_express(&a));
  1706.        if (tag <= 0)
  1707.         int_error("tag must be > zero", c_token);
  1708.     } else
  1709.      tag = assign_arrow_tag(); /* default next tag */
  1710.      
  1711.     /* get start position */
  1712.     if (!END_OF_COMMAND && equals(c_token, "from")) {
  1713.        c_token++;
  1714.        if (END_OF_COMMAND)
  1715.         int_error("start coordinates expected", c_token);
  1716.        /* get coordinates */
  1717.        sx = real(const_express(&a));
  1718.        if (!equals(c_token,","))
  1719.         int_error("',' expected",c_token);
  1720.        c_token++;
  1721.        sy = real(const_express(&a));
  1722.        if (equals(c_token,",")) {
  1723.         c_token++;
  1724.         sz = real(const_express(&a));
  1725.        }
  1726.        else
  1727.            sz = 0;
  1728.        set_start = TRUE;
  1729.     } else {
  1730.        sx = sy = sz = 0;            /* default at origin */
  1731.        set_start = FALSE;
  1732.     }
  1733.  
  1734.     /* get end position */
  1735.     if (!END_OF_COMMAND && equals(c_token, "to")) {
  1736.        c_token++;
  1737.        if (END_OF_COMMAND)
  1738.         int_error("end coordinates expected", c_token);
  1739.        /* get coordinates */
  1740.        ex = real(const_express(&a));
  1741.        if (!equals(c_token,","))
  1742.         int_error("',' expected",c_token);
  1743.        c_token++;
  1744.        ey = real(const_express(&a));
  1745.        if (equals(c_token,",")) {
  1746.         c_token++;
  1747.         ez = real(const_express(&a));
  1748.        }
  1749.        else
  1750.         ez = 0;
  1751.        set_end = TRUE;
  1752.     } else {
  1753.        ex = ey = ez = 0;            /* default at origin */
  1754.        set_end = FALSE;
  1755.     }
  1756.  
  1757.     /* get start position - what the heck, either order is ok */
  1758.     if (!END_OF_COMMAND && equals(c_token, "from")) {
  1759.        if (set_start)
  1760.         int_error("only one 'from' is allowed", c_token);
  1761.        c_token++;
  1762.        if (END_OF_COMMAND)
  1763.         int_error("start coordinates expected", c_token);
  1764.        /* get coordinates */
  1765.        sx = real(const_express(&a));
  1766.        if (!equals(c_token,","))
  1767.         int_error("',' expected",c_token);
  1768.        c_token++;
  1769.        sy = real(const_express(&a));
  1770.        if (equals(c_token,",")) {
  1771.         c_token++;
  1772.         sz = real(const_express(&a));
  1773.        }
  1774.        else
  1775.            sz = 0;
  1776.        set_start = TRUE;
  1777.     }
  1778.  
  1779.     if (!END_OF_COMMAND && equals(c_token, "nohead")) {
  1780.        c_token++;
  1781.            head = 0;
  1782.     }
  1783.  
  1784.     if (!END_OF_COMMAND && equals(c_token, "head")) {
  1785.        c_token++;
  1786.            head = 1;
  1787.     }
  1788.  
  1789.     if (!END_OF_COMMAND)
  1790.      int_error("extraneous or out-of-order arguments in set arrow", c_token);
  1791.  
  1792.     /* OK! add arrow */
  1793.     if (first_arrow != NULL) { /* skip to last arrow */
  1794.        for (this_arrow = first_arrow; this_arrow != NULL ; 
  1795.            prev_arrow = this_arrow, this_arrow = this_arrow->next)
  1796.         /* is this the arrow we want? */
  1797.         if (tag <= this_arrow->tag)
  1798.           break;
  1799.     }
  1800.     if (this_arrow != NULL && tag == this_arrow->tag) {
  1801.        /* changing the arrow */
  1802.        if (set_start) {
  1803.           this_arrow->sx = sx;
  1804.           this_arrow->sy = sy;
  1805.           this_arrow->sz = sz;
  1806.        }
  1807.        if (set_end) {
  1808.           this_arrow->ex = ex;
  1809.           this_arrow->ey = ey;
  1810.           this_arrow->ez = ez;
  1811.        }
  1812.        this_arrow->head = head;
  1813.     } else {
  1814.        /* adding the arrow */
  1815.        new_arrow = (struct arrow_def *) 
  1816.         alloc ( (unsigned long) sizeof(struct arrow_def), "arrow");
  1817.        if (prev_arrow != NULL)
  1818.         prev_arrow->next = new_arrow; /* add it to end of list */
  1819.        else 
  1820.         first_arrow = new_arrow; /* make it start of list */
  1821.        new_arrow->tag = tag;
  1822.        new_arrow->next = this_arrow;
  1823.        new_arrow->sx = sx;
  1824.        new_arrow->sy = sy;
  1825.        new_arrow->sz = sz;
  1826.        new_arrow->ex = ex;
  1827.        new_arrow->ey = ey;
  1828.        new_arrow->ez = ez;
  1829.        new_arrow->head = head;
  1830.     }
  1831. }
  1832. #endif
  1833.  
  1834. #ifdef THINK_C_1
  1835. /* process 'set noarrow' command */
  1836. /* set noarrow {tag} */
  1837. static void
  1838. set_noarrow()
  1839. {
  1840.     struct value a;
  1841.     struct arrow_def *this_arrow;
  1842.     struct arrow_def *prev_arrow; 
  1843.     int tag;
  1844.  
  1845.     if (END_OF_COMMAND) {
  1846.        /* delete all arrows */
  1847.        while (first_arrow != NULL)
  1848.         delete_arrow((struct arrow_def *)NULL,first_arrow);
  1849.     }
  1850.     else {
  1851.        /* get tag */
  1852.        tag = (int)real(const_express(&a));
  1853.        if (!END_OF_COMMAND)
  1854.         int_error("extraneous arguments to set noarrow", c_token);
  1855.        for (this_arrow = first_arrow, prev_arrow = NULL;
  1856.            this_arrow != NULL;
  1857.            prev_arrow = this_arrow, this_arrow = this_arrow->next) {
  1858.           if (this_arrow->tag == tag) {
  1859.              delete_arrow(prev_arrow,this_arrow);
  1860.              return;        /* exit, our job is done */
  1861.           }
  1862.        }
  1863.        int_error("arrow not found", c_token);
  1864.     }
  1865. }
  1866. #endif
  1867.  
  1868. #ifdef THINK_C_1
  1869. /* assign a new arrow tag */
  1870. /* arrows are kept sorted by tag number, so this is easy */
  1871. static int                /* the lowest unassigned tag number */
  1872. assign_arrow_tag()
  1873. {
  1874.     struct arrow_def *this_arrow;
  1875.     int last = 0;            /* previous tag value */
  1876.  
  1877.     for (this_arrow = first_arrow; this_arrow != NULL;
  1878.         this_arrow = this_arrow->next)
  1879.      if (this_arrow->tag == last+1)
  1880.        last++;
  1881.      else
  1882.        break;
  1883.  
  1884.     return (last+1);
  1885. }
  1886. #endif
  1887.  
  1888. #ifdef THINK_C_1
  1889. /* delete arrow from linked list started by first_arrow.
  1890.  * called with pointers to the previous arrow (prev) and the 
  1891.  * arrow to delete (this).
  1892.  * If there is no previous arrow (the arrow to delete is
  1893.  * first_arrow) then call with prev = NULL.
  1894.  */
  1895. static void
  1896. delete_arrow(prev,this)
  1897.     struct arrow_def *prev, *this;
  1898. {
  1899.     if (this!=NULL)    {        /* there really is something to delete */
  1900.        if (prev!=NULL)        /* there is a previous arrow */
  1901.         prev->next = this->next; 
  1902.        else                /* this = first_arrow so change first_arrow */
  1903.         first_arrow = this->next;
  1904.        free((char *)this);
  1905.     }
  1906. }
  1907. #endif
  1908.  
  1909. #ifdef THINK_C_1
  1910. enum PLOT_STYLE            /* not static; used by command.c */
  1911. get_style()
  1912. {
  1913. register enum PLOT_STYLE ps;
  1914.  
  1915.     c_token++;
  1916.     if (almost_equals(c_token,"l$ines"))
  1917.         ps = LINES;
  1918.     else if (almost_equals(c_token,"i$mpulses"))
  1919.         ps = IMPULSES;
  1920.     else if (almost_equals(c_token,"p$oints"))
  1921.         ps = POINTSTYLE;
  1922.     else if (almost_equals(c_token,"linesp$oints"))
  1923.         ps = LINESPOINTS;
  1924.     else if (almost_equals(c_token,"d$ots"))
  1925.         ps = DOTS;
  1926.     else if (almost_equals(c_token,"e$rrorbars"))
  1927.         ps = ERRORBARS;
  1928.     else if (almost_equals(c_token,"b$oxes"))
  1929.         ps = BOXES;
  1930.     else if (almost_equals(c_token,"boxer$rorbars"))
  1931.         ps = BOXERROR;
  1932.     else if (almost_equals(c_token,"s$teps"))
  1933.         ps = STEPS;
  1934.     else
  1935.         int_error("expecting 'lines', 'points', 'linespoints', 'dots', 'impulses', \n\
  1936.         'errorbars', 'steps', 'boxes' or 'boxerrorbars'",c_token);
  1937.     c_token++;
  1938.     return(ps);
  1939. }
  1940. #endif
  1941.  
  1942. #ifdef THINK_C_1
  1943. /* For set [xy]tics... command*/
  1944. static void
  1945. load_tics(tdef)
  1946.     struct ticdef *tdef;    /* change this ticdef */
  1947. {
  1948.     if (equals(c_token,"(")) { /* set : TIC_USER */
  1949.        c_token++;
  1950.        load_tic_user(tdef);
  1951.     } else {                /* series : TIC_SERIES */
  1952.        load_tic_series(tdef);
  1953.     }
  1954. }
  1955. #endif
  1956.  
  1957. #ifdef THINK_C_1
  1958. /* load TIC_USER definition */
  1959. /* (tic[,tic]...)
  1960.  * where tic is ["string"] value
  1961.  * Left paren is already scanned off before entry.
  1962.  */
  1963. static void
  1964. load_tic_user(tdef)
  1965.     struct ticdef *tdef;
  1966. {
  1967.     struct ticmark *list = NULL; /* start of list */
  1968.     struct ticmark *last = NULL; /* end of list */
  1969.     struct ticmark *tic = NULL; /* new ticmark */
  1970.     char temp_string[MAX_LINE_LEN];
  1971.     struct value a;
  1972.  
  1973.     while (!END_OF_COMMAND) {
  1974.        /* parse a new ticmark */
  1975.        tic = (struct ticmark *)alloc((unsigned long)sizeof(struct ticmark), (char *)NULL);
  1976.        if (tic == (struct ticmark *)NULL) {
  1977.           free_marklist(list);
  1978.           int_error("out of memory for tic mark", c_token);
  1979.        }
  1980.  
  1981.        /* has a string with it? */
  1982.        if (isstring(c_token)) {
  1983.           quote_str(temp_string,c_token);
  1984.           tic->label = alloc((unsigned long)strlen(temp_string)+1, "tic label");
  1985.           (void) strcpy(tic->label, temp_string);
  1986.           c_token++;
  1987.        } else
  1988.         tic->label = NULL;
  1989.  
  1990.        /* in any case get the value */
  1991.        tic->position = real(const_express(&a));
  1992.        tic->next = NULL;
  1993.  
  1994.        /* append to list */
  1995.        if (list == NULL)
  1996.         last = list = tic;    /* new list */
  1997.        else {                /* append to list */
  1998.           last->next = tic;
  1999.           last = tic;
  2000.        }
  2001.  
  2002.        /* expect "," or ")" here */
  2003.        if (!END_OF_COMMAND && equals(c_token, ","))
  2004.         c_token++;        /* loop again */
  2005.        else
  2006.         break;            /* hopefully ")" */
  2007.     }
  2008.     
  2009.     if (END_OF_COMMAND || !equals(c_token, ")")) {
  2010.        free_marklist(list);
  2011.        int_error("expecting right parenthesis )", c_token);
  2012.     }
  2013.     c_token++;
  2014.     
  2015.     /* successful list */
  2016.     if (tdef->type == TIC_USER) {
  2017.        /* remove old list */
  2018.         /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  2019.        free_marklist(tdef->def.user);
  2020.        tdef->def.user = NULL;
  2021.     }
  2022.     tdef->type = TIC_USER;
  2023.     tdef->def.user = list;
  2024. }
  2025. #endif
  2026.  
  2027. #ifdef THINK_C_1
  2028. static void
  2029. free_marklist(list)
  2030.     struct ticmark *list;
  2031. {
  2032.     register struct ticmark *freeable;
  2033.  
  2034.     while (list != NULL) {
  2035.        freeable = list;
  2036.        list = list->next;
  2037.        if (freeable->label != NULL)
  2038.         free( (char *)freeable->label );
  2039.        free( (char *)freeable );
  2040.     }
  2041. }
  2042. #endif
  2043.  
  2044. #ifdef THINK_C_1
  2045. /* load TIC_SERIES definition */
  2046. /* start,incr[,end] */
  2047. static void
  2048. load_tic_series(tdef)
  2049.     struct ticdef *tdef;
  2050. {
  2051.     double start, incr, end;
  2052.     struct value a;
  2053.     int incr_token;
  2054.  
  2055.     start = real(const_express(&a));
  2056.     if (!equals(c_token, ","))
  2057.      int_error("expecting comma to separate start,incr", c_token);
  2058.     c_token++;
  2059.  
  2060.     incr_token = c_token;
  2061.     incr = real(const_express(&a));
  2062.  
  2063.     if (END_OF_COMMAND)
  2064.      end = VERYLARGE;
  2065.     else {
  2066.        if (!equals(c_token, ","))
  2067.         int_error("expecting comma to separate incr,end", c_token);
  2068.        c_token++;
  2069.  
  2070.        end = real(const_express(&a));
  2071.     }
  2072.     if (!END_OF_COMMAND)
  2073.      int_error("tic series is defined by start,increment[,end]", 
  2074.              c_token);
  2075.     
  2076.     if (start < end && incr <= 0)
  2077.      int_error("increment must be positive", incr_token);
  2078.     if (start > end && incr >= 0)
  2079.      int_error("increment must be negative", incr_token);
  2080.     if (start > end) {
  2081.        /* put in order */
  2082.         double numtics;
  2083.         numtics = floor( (end*(1+SIGNIF) - start)/incr );
  2084.         end = start;
  2085.         start = end + numtics*incr;
  2086.         incr = -incr;
  2087. /*
  2088.        double temp = start;
  2089.        start = end;
  2090.        end = temp;
  2091.        incr = -incr;
  2092.  */
  2093.     }
  2094.  
  2095.     if (tdef->type == TIC_USER) {
  2096.        /* remove old list */
  2097.         /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  2098.        free_marklist(tdef->def.user);
  2099.        tdef->def.user = NULL;
  2100.     }
  2101.     tdef->type = TIC_SERIES;
  2102.     tdef->def.series.start = start;
  2103.     tdef->def.series.incr = incr;
  2104.     tdef->def.series.end = end;
  2105. }
  2106. #endif
  2107.  
  2108. #ifdef THINK_C_1
  2109. static void
  2110. load_offsets (a, b, c, d)
  2111. double *a,*b, *c, *d;
  2112. {
  2113. struct value t;
  2114.  
  2115.     *a = real (const_express(&t));  /* loff value */
  2116.     c_token++;
  2117.     if (equals(c_token,","))
  2118.         c_token++;
  2119.     if (END_OF_COMMAND) 
  2120.         return;
  2121.  
  2122.     *b = real (const_express(&t));  /* roff value */
  2123.     c_token++;
  2124.     if (equals(c_token,","))
  2125.         c_token++;
  2126.     if (END_OF_COMMAND) 
  2127.         return;
  2128.  
  2129.     *c = real (const_express(&t));  /* toff value */
  2130.     c_token++;
  2131.     if (equals(c_token,","))
  2132.         c_token++;
  2133.     if (END_OF_COMMAND) 
  2134.         return;
  2135.  
  2136.     *d = real (const_express(&t));  /* boff value */
  2137.     c_token++;
  2138. }
  2139. #endif
  2140.  
  2141. #ifdef THINK_C_1
  2142. TBOOLEAN                    /* TRUE if a or b were changed */
  2143. load_range(a,b)            /* also used by command.c */
  2144. double *a,*b;
  2145. {
  2146. struct value t;
  2147. TBOOLEAN changed = FALSE;
  2148.  
  2149.     if (equals(c_token,"]"))
  2150.         return(FALSE);
  2151.     if (END_OF_COMMAND) {
  2152.         int_error("starting range value or ':' or 'to' expected",c_token);
  2153.     } else if (!equals(c_token,"to") && !equals(c_token,":"))  {
  2154.         *a = real(const_express(&t));
  2155.         changed = TRUE;
  2156.     }    
  2157.     if (!equals(c_token,"to") && !equals(c_token,":"))
  2158.         int_error("':' or keyword 'to' expected",c_token);
  2159.     c_token++;
  2160.     if (!equals(c_token,"]")) {
  2161.         *b = real(const_express(&t));
  2162.         changed = TRUE;
  2163.      }
  2164.      return(changed);
  2165. }
  2166. #endif
  2167.  
  2168. #ifdef THINK_C_2
  2169. /******* The 'show' command *******/
  2170. void
  2171. show_command()
  2172. {
  2173.     static char GPFAR showmess[] = 
  2174.     "valid show options:  'action_table', 'all', 'angles', 'arrow', \n\
  2175.     'autoscale', 'border', 'boxwidth', 'clip', 'contour', 'data', \n\
  2176.     'dgrid3d', 'dummy', 'format', 'function', 'grid', 'hidden', 'key', \n\
  2177.     'label', 'logscale', 'mapping',  'offsets', 'output', 'plot', \n\
  2178.     'parametric', 'polar', 'rrange', 'samples', 'isosamples', 'view', \n\
  2179.     'size', 'terminal', 'tics', 'ticslevel', 'time', 'title', 'trange', \n\
  2180.     'urange', 'vrange', 'variables', 'version', \n\
  2181.     'xlabel', 'xrange', '{no}xtics', 'xmtics', 'xdtics', '{no}xzeroaxis',\n\
  2182.     'ylabel', 'yrange', '{no}ytics', 'ymtics', 'ydtics', '{no}yzeroaxis',\n\
  2183.      'zero', '{no}zeroaxis', 'zlabel', 'zrange', '{no}ztics',\n\
  2184.      'zmtics', 'zdtics'";
  2185.  
  2186.     c_token++;
  2187.  
  2188.     if (!show_one() && !show_two())
  2189.     int_error(showmess, c_token);
  2190.     screen_ok = FALSE;
  2191.     (void) putc('\n',stderr);
  2192. }
  2193. #endif
  2194.  
  2195. #ifdef THINK_C_2
  2196. /* return TRUE if a command match, FALSE if not */
  2197. static TBOOLEAN
  2198. show_one()
  2199. {
  2200.     if (almost_equals(c_token,"ac$tion_table") ||
  2201.              equals(c_token,"at") ) {
  2202.         c_token++; 
  2203.         show_at();
  2204.         c_token++;
  2205.     }
  2206.     else if (almost_equals(c_token,"ar$row")) {
  2207.         struct value a;
  2208.         int tag = 0;
  2209.  
  2210.         c_token++;
  2211.         if (!END_OF_COMMAND) {
  2212.            tag = (int)real(const_express(&a));
  2213.            if (tag <= 0)
  2214.             int_error("tag must be > zero", c_token);
  2215.         }
  2216.  
  2217.         (void) putc('\n',stderr);
  2218.         show_arrow(tag);
  2219.     }
  2220.     else if (almost_equals(c_token,"au$toscale")) {
  2221.         (void) putc('\n',stderr);
  2222.         show_autoscale();
  2223.         c_token++;
  2224.     }
  2225.     else if (almost_equals(c_token,"bor$der")) {
  2226.         (void) putc('\n',stderr);
  2227.         show_border();
  2228.         c_token++;
  2229.     }
  2230.     else if (almost_equals(c_token,"box$width")) {
  2231.         (void) putc('\n',stderr);
  2232.         show_boxwidth();
  2233.         c_token++;
  2234.     }
  2235.     else if (almost_equals(c_token,"c$lip")) {
  2236.         (void) putc('\n',stderr);
  2237.         show_clip();
  2238.         c_token++;
  2239.     }
  2240.     else if (almost_equals(c_token,"ma$pping")) {
  2241.         (void) putc('\n',stderr);
  2242.         show_mapping();
  2243.         c_token++;
  2244.     }
  2245.     else if (almost_equals(c_token,"co$ntour")) {
  2246.         (void) putc('\n',stderr);
  2247.         show_contour();
  2248.         c_token++;
  2249.     }
  2250.     else if (almost_equals(c_token,"da$ta")) {
  2251.         c_token++;
  2252.         if (!almost_equals(c_token,"s$tyle"))
  2253.             int_error("expecting keyword 'style'",c_token);
  2254.         (void) putc('\n',stderr);
  2255.         show_style("data",data_style);
  2256.         c_token++;
  2257.     }
  2258.     else if (almost_equals(c_token,"dg$rid3d")) {
  2259.         (void) putc('\n',stderr);
  2260.         show_dgrid3d();
  2261.         c_token++;
  2262.     }
  2263.     else if (almost_equals(c_token,"du$mmy")) {
  2264.           (void) fprintf(stderr,"\n\tdummy variables are \"%s\" and \"%s\"\n",
  2265.                         dummy_var[0], dummy_var[1]);
  2266.         c_token++;
  2267.     }
  2268.     else if (almost_equals(c_token,"fo$rmat")) {
  2269.         show_format();
  2270.         c_token++;
  2271.     }
  2272.     else if (almost_equals(c_token,"fu$nctions")) {
  2273.         c_token++;
  2274.         if (almost_equals(c_token,"s$tyle"))  {
  2275.             (void) putc('\n',stderr);
  2276.             show_style("functions",func_style);
  2277.             c_token++;
  2278.         }
  2279.         else
  2280.             show_functions();
  2281.     }
  2282.     else if (almost_equals(c_token,"lo$gscale")) {
  2283.         (void) putc('\n',stderr);
  2284.         show_logscale();
  2285.         c_token++;
  2286.     }
  2287.     else if (almost_equals(c_token,"of$fsets")) {
  2288.         (void) putc('\n',stderr);
  2289.         show_offsets();
  2290.         c_token++;
  2291.     }
  2292.     else if (almost_equals(c_token,"o$utput")) {
  2293.         (void) putc('\n',stderr);
  2294.         show_output();
  2295.         c_token++;
  2296.     }
  2297.     else if (almost_equals(c_token,"tit$le")) {
  2298.         (void) putc('\n',stderr);
  2299.         show_title();
  2300.         c_token++;
  2301.     }
  2302.     else if (almost_equals(c_token,"xl$abel")) {
  2303.         (void) putc('\n',stderr);
  2304.         show_xlabel();
  2305.         c_token++;
  2306.     }
  2307.     else if (almost_equals(c_token,"yl$abel")) {
  2308.         (void) putc('\n',stderr);
  2309.         show_ylabel();
  2310.         c_token++;
  2311.     }
  2312.     else if (almost_equals(c_token,"zl$abel")) {
  2313.         (void) putc('\n',stderr);
  2314.         show_zlabel();
  2315.         c_token++;
  2316.     }
  2317.     else if (almost_equals(c_token,"xzero$axis")) {
  2318.         (void) putc('\n',stderr);
  2319.         show_xzeroaxis();
  2320.         c_token++;
  2321.     }
  2322.     else if (almost_equals(c_token,"yzero$axis")) {
  2323.         (void) putc('\n',stderr);
  2324.         show_yzeroaxis();
  2325.         c_token++;
  2326.     }
  2327.     else if (almost_equals(c_token,"zeroa$xis")) {
  2328.         (void) putc('\n',stderr);
  2329.         show_xzeroaxis();
  2330.         show_yzeroaxis();
  2331.         c_token++;
  2332.     }
  2333.     else if (almost_equals(c_token,"la$bel")) {
  2334.         struct value a;
  2335.         int tag = 0;
  2336.  
  2337.         c_token++;
  2338.         if (!END_OF_COMMAND) {
  2339.            tag = (int)real(const_express(&a));
  2340.            if (tag <= 0)
  2341.             int_error("tag must be > zero", c_token);
  2342.         }
  2343.  
  2344.         (void) putc('\n',stderr);
  2345.         show_label(tag);
  2346.     }
  2347.     else if (almost_equals(c_token,"g$rid")) {
  2348.         (void) putc('\n',stderr);
  2349.         show_grid();
  2350.         c_token++;
  2351.     }
  2352.     else if (almost_equals(c_token,"k$ey")) {
  2353.         (void) putc('\n',stderr);
  2354.         show_key();
  2355.         c_token++;
  2356.     }
  2357.     else
  2358.         return (FALSE);
  2359.     return TRUE;
  2360. }
  2361. #endif
  2362.  
  2363. #ifdef THINK_C_2
  2364. /* return TRUE if a command match, FALSE if not */
  2365. static TBOOLEAN
  2366. show_two()
  2367. {
  2368.     if (almost_equals(c_token,"p$lot")) {
  2369.         (void) putc('\n',stderr);
  2370.         show_plot();
  2371.         c_token++;
  2372.     }
  2373.     else if (almost_equals(c_token,"par$ametric")) {
  2374.         (void) putc('\n',stderr);
  2375.         show_parametric();
  2376.         c_token++;
  2377.     }
  2378.     else if (almost_equals(c_token,"pol$ar")) {
  2379.         (void) putc('\n',stderr);
  2380.         show_polar();
  2381.         c_token++;
  2382.     }
  2383.     else if (almost_equals(c_token,"an$gles")) {
  2384.         (void) putc('\n',stderr);
  2385.         show_angles();
  2386.         c_token++;
  2387.     }
  2388.     else if (almost_equals(c_token,"ti$cs")) {
  2389.         (void) putc('\n',stderr);
  2390.         show_tics(TRUE,TRUE,TRUE);
  2391.         c_token++;
  2392.     }
  2393.     else if (almost_equals(c_token,"tim$e")) {
  2394.         (void) putc('\n',stderr);
  2395.         show_time();
  2396.         c_token++;
  2397.     }
  2398.     else if (almost_equals(c_token,"su$rface")) {
  2399.         (void) putc('\n',stderr);
  2400.         show_surface();
  2401.         c_token++;
  2402.     }
  2403.     else if (almost_equals(c_token,"hi$dden3d")) {
  2404.         (void) putc('\n',stderr);
  2405.         show_hidden3d();
  2406.         c_token++;
  2407.     }
  2408.      else if (almost_equals(c_token,"cla$bel")) {
  2409.          (void) putc('\n',stderr);
  2410.          show_label_contours();
  2411.          c_token++;
  2412.      }
  2413.     else if (almost_equals(c_token,"xti$cs")) {
  2414.         show_tics(TRUE,FALSE,FALSE);
  2415.         c_token++;
  2416.     }
  2417.     else if (almost_equals(c_token,"yti$cs")) {
  2418.         show_tics(FALSE,TRUE,FALSE);
  2419.         c_token++;
  2420.     }
  2421.     else if (almost_equals(c_token,"zti$cs")) {
  2422.         show_tics(FALSE,FALSE,TRUE);
  2423.         c_token++;
  2424.     }
  2425.     else if (almost_equals(c_token,"sa$mples")) {
  2426.         (void) putc('\n',stderr);
  2427.         show_samples();
  2428.         c_token++;
  2429.     }
  2430.     else if (almost_equals(c_token,"isosa$mples")) {
  2431.         (void) putc('\n',stderr);
  2432.         show_isosamples();
  2433.         c_token++;
  2434.     }
  2435.     else if (almost_equals(c_token,"si$ze")) {
  2436.         (void) putc('\n',stderr);
  2437.         show_size();
  2438.         c_token++;
  2439.     }
  2440.     else if (almost_equals(c_token,"t$erminal")) {
  2441.         (void) putc('\n',stderr);
  2442.         show_term();
  2443.         c_token++;
  2444.     }
  2445.     else if (almost_equals(c_token,"rr$ange")) {
  2446.         (void) putc('\n',stderr);
  2447.         show_range('r',rmin,rmax);
  2448.         c_token++;
  2449.     }
  2450.     else if (almost_equals(c_token,"tr$ange")) {
  2451.         (void) putc('\n',stderr);
  2452.         show_range('t',tmin,tmax);
  2453.         c_token++;
  2454.     }
  2455.     else if (almost_equals(c_token,"ur$ange")) {
  2456.         (void) putc('\n',stderr);
  2457.         show_range('u',umin,umax);
  2458.         c_token++;
  2459.     }
  2460.     else if (almost_equals(c_token,"vi$ew")) {
  2461.         (void) putc('\n',stderr);
  2462.         show_view();
  2463.         c_token++;
  2464.     }
  2465.     else if (almost_equals(c_token,"vr$ange")) {
  2466.         (void) putc('\n',stderr);
  2467.         show_range('v',vmin,vmax);
  2468.         c_token++;
  2469.     }
  2470.     else if (almost_equals(c_token,"v$ariables")) {
  2471.         show_variables();
  2472.         c_token++;
  2473.     }
  2474.     else if (almost_equals(c_token,"ve$rsion")) {
  2475.         show_version();
  2476.         c_token++;
  2477.     }
  2478.     else if (almost_equals(c_token,"xr$ange")) {
  2479.         (void) putc('\n',stderr);
  2480.         show_range('x',xmin,xmax);
  2481.         c_token++;
  2482.     }
  2483.     else if (almost_equals(c_token,"yr$ange")) {
  2484.         (void) putc('\n',stderr);
  2485.         show_range('y',ymin,ymax);
  2486.         c_token++;
  2487.     }
  2488.     else if (almost_equals(c_token,"zr$ange")) {
  2489.         (void) putc('\n',stderr);
  2490.         show_range('z',zmin,zmax);
  2491.         c_token++;
  2492.     }
  2493.     else if (almost_equals(c_token,"z$ero")) {
  2494.         (void) putc('\n',stderr);
  2495.         show_zero();
  2496.         c_token++;
  2497.     }
  2498.     else if (almost_equals(c_token,"a$ll")) {
  2499.         c_token++;
  2500.         show_version();
  2501.         show_autoscale();
  2502.         show_border();
  2503.         show_boxwidth();
  2504.         show_clip();
  2505.         show_contour();
  2506.         show_dgrid3d();
  2507.         show_mapping();
  2508.           (void) fprintf(stderr,"\tdummy variables are \"%s\" and \"%s\"\n",
  2509.                         dummy_var[0], dummy_var[1]);
  2510.         show_format();
  2511.         show_style("data",data_style);
  2512.         show_style("functions",func_style);
  2513.         show_grid();
  2514.         show_label(0);
  2515.         show_arrow(0);
  2516.         show_key();
  2517.         show_logscale();
  2518.         show_offsets();
  2519.         show_output();
  2520.         show_parametric();
  2521.         show_polar();
  2522.         show_angles();
  2523.         show_samples();
  2524.         show_isosamples();
  2525.         show_view();
  2526.         show_surface();
  2527. #ifndef LITE
  2528.         show_hidden3d();
  2529. #endif
  2530.         show_size();
  2531.         show_term();
  2532.         show_tics(TRUE,TRUE,TRUE);
  2533.         show_time();
  2534.         if (parametric)
  2535.             if (!is_3d_plot)
  2536.                 show_range('t',tmin,tmax);
  2537.             else {
  2538.                 show_range('u',umin,umax);
  2539.                 show_range('v',vmin,vmax);
  2540.             }
  2541.         if (polar)
  2542.           show_range('r',rmin,rmax);
  2543.         show_range('x',xmin,xmax);
  2544.         show_range('y',ymin,ymax);
  2545.         show_range('z',zmin,zmax);
  2546.         show_title();
  2547.         show_xlabel();
  2548.         show_ylabel();
  2549.         show_zlabel();
  2550.         show_zero();
  2551.         show_plot();
  2552.         show_variables();
  2553.         show_functions();
  2554.         c_token++;
  2555.     }
  2556.     else
  2557.         return (FALSE);
  2558.     return (TRUE);
  2559. }
  2560. #endif
  2561.  
  2562. #ifdef THINK_C_2
  2563. /*********** support functions for 'show'  **********/
  2564. static void
  2565. show_style(name,style)
  2566. char name[];
  2567. enum PLOT_STYLE style;
  2568. {
  2569.     fprintf(stderr,"\t%s are plotted with ",name);
  2570.     switch (style) {
  2571.         case LINES: fprintf(stderr,"lines\n"); break;
  2572.         case POINTSTYLE: fprintf(stderr,"points\n"); break;
  2573.         case IMPULSES: fprintf(stderr,"impulses\n"); break;
  2574.         case LINESPOINTS: fprintf(stderr,"linespoints\n"); break;
  2575.         case DOTS: fprintf(stderr,"dots\n"); break;
  2576.         case ERRORBARS: fprintf(stderr,"errorbars\n"); break;
  2577.         case BOXES: fprintf(stderr,"boxes\n"); break;
  2578.         case BOXERROR: fprintf(stderr,"boxerrorbars\n"); break;
  2579.         case STEPS: fprintf(stderr,"steps\n"); break;
  2580.     }
  2581. }
  2582. #endif
  2583.  
  2584. #ifdef THINK_C_2
  2585. static void
  2586. show_boxwidth()
  2587. {
  2588.     if (boxwidth<0.0)
  2589.         fprintf(stderr,"\tboxwidth is auto\n");
  2590.     else
  2591.         fprintf(stderr,"\tboxwidth is %g\n",boxwidth);
  2592. }
  2593. #endif
  2594.  
  2595. #ifdef THINK_C_2
  2596. static void
  2597. show_dgrid3d()
  2598. {
  2599.     if (dgrid3d)
  2600.         fprintf(stderr,"\tdata grid3d is enabled for mesh of size %dx%d, norm=%d\n",
  2601.             dgrid3d_row_fineness,
  2602.             dgrid3d_col_fineness,
  2603.             dgrid3d_norm_value);
  2604.     else
  2605.         fprintf(stderr,"\tdata grid3d is disabled\n");
  2606. }
  2607. #endif
  2608.  
  2609. #ifdef THINK_C_2
  2610. static void
  2611. show_range(name,min,max)
  2612. char name;
  2613. double min,max;
  2614. {
  2615.     fprintf(stderr,"\t%crange is [%g : %g]\n",name,min,max);
  2616. }
  2617. #endif
  2618.  
  2619. #ifdef THINK_C_2
  2620. static void
  2621. show_zero()
  2622. {
  2623.     fprintf(stderr,"\tzero is %g\n",zero);
  2624. }
  2625. #endif
  2626.  
  2627. #ifdef THINK_C_2
  2628. static void
  2629. show_offsets()
  2630. {
  2631.     fprintf(stderr,"\toffsets are %g, %g, %g, %g\n",loff,roff,toff,boff);
  2632. }
  2633. #endif
  2634.  
  2635. #ifdef THINK_C_2
  2636. static void
  2637. show_border()
  2638. {
  2639.     fprintf(stderr,"\tborder is %sdrawn\n", draw_border ? "" : "not ");
  2640. }
  2641. #endif
  2642.  
  2643. #ifdef THINK_C_2
  2644. static void
  2645. show_output()
  2646. {
  2647.     fprintf(stderr,"\toutput is sent to %s\n",outstr);
  2648. }
  2649. #endif
  2650.  
  2651. #ifdef THINK_C_2
  2652. static void
  2653. show_samples()
  2654. {
  2655.     fprintf(stderr,"\tsampling rate is %d, %d\n",samples_1, samples_2);
  2656. }
  2657. #endif
  2658.  
  2659. #ifdef THINK_C_2
  2660. static void
  2661. show_isosamples()
  2662. {
  2663.     fprintf(stderr,"\tiso sampling rate is %d, %d\n",
  2664.         iso_samples_1, iso_samples_2);
  2665. }
  2666. #endif
  2667.  
  2668. #ifdef THINK_C_2
  2669. static void
  2670. show_surface()
  2671. {
  2672.     fprintf(stderr,"\tsurface is %sdrawn\n", draw_surface ? "" : "not ");
  2673. }
  2674. #endif
  2675.  
  2676. #ifdef THINK_C_2
  2677. static void
  2678. show_hidden3d()
  2679. {
  2680. #ifdef LITE
  2681.     printf(" Hidden Line Removal Not Supported in LITE version\n");
  2682. #else
  2683.     fprintf(stderr,"\thidden surface is %s\n", hidden3d ? "removed" : "drawn");
  2684. #endif /* LITE */
  2685. }
  2686. #endif
  2687.  
  2688. #ifdef THINK_C_2
  2689. static void
  2690. show_label_contours()
  2691. {
  2692.     fprintf(stderr,"\tcontour line types are %s\n", label_contours ? "varied & labeled" : "all the same");
  2693. }
  2694. #endif
  2695.  
  2696. #ifdef THINK_C_2
  2697. static void
  2698. show_view()
  2699. {
  2700.     fprintf(stderr,"\tview is %g rot_x, %g rot_z, %g scale, %g scale_z\n",
  2701.         surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
  2702. }
  2703. #endif
  2704.  
  2705. #ifdef THINK_C_2
  2706. static void
  2707. show_size()
  2708. {
  2709.     fprintf(stderr,"\tsize is scaled by %g,%g\n",xsize,ysize);
  2710. }
  2711. #endif
  2712.  
  2713. #ifdef THINK_C_2
  2714. static void
  2715. show_title()
  2716. {
  2717.     fprintf(stderr,"\ttitle is \"%s\", offset at %d, %d\n",
  2718.         title,title_xoffset,title_yoffset);
  2719. }
  2720. #endif
  2721.  
  2722. #ifdef THINK_C_2
  2723. static void
  2724. show_xlabel()
  2725. {
  2726.     fprintf(stderr,"\txlabel is \"%s\", offset at %d, %d\n",
  2727.         xlabel,xlabel_xoffset,xlabel_yoffset);
  2728. }
  2729. #endif
  2730.  
  2731. #ifdef THINK_C_2
  2732. static void
  2733. show_ylabel()
  2734. {
  2735.     fprintf(stderr,"\tylabel is \"%s\", offset at %d, %d\n",
  2736.         ylabel,ylabel_xoffset,ylabel_yoffset);
  2737. }
  2738. #endif
  2739.  
  2740. #ifdef THINK_C_2
  2741. static void
  2742. show_zlabel()
  2743. {
  2744.     fprintf(stderr,"\tzlabel is \"%s\", offset at %d, %d\n",
  2745.         zlabel,zlabel_xoffset,zlabel_yoffset);
  2746. }
  2747. #endif
  2748.  
  2749. #ifdef THINK_C_2
  2750. static void
  2751. show_xzeroaxis()
  2752. {
  2753.     fprintf(stderr,"\txzeroaxis is %s\n",(xzeroaxis)? "ON" : "OFF");
  2754. }
  2755. #endif
  2756.  
  2757. #ifdef THINK_C_2
  2758. static void
  2759. show_yzeroaxis()
  2760. {
  2761.     fprintf(stderr,"\tyzeroaxis is %s\n",(yzeroaxis)? "ON" : "OFF");
  2762. }
  2763. #endif
  2764.  
  2765. #ifdef THINK_C_2
  2766. static void
  2767. show_label(tag)
  2768.     int tag;                /* 0 means show all */
  2769. {
  2770.     struct text_label *this_label;
  2771.     TBOOLEAN showed = FALSE;
  2772.  
  2773.     for (this_label = first_label; this_label != NULL;
  2774.         this_label = this_label->next) {
  2775.        if (tag == 0 || tag == this_label->tag) {
  2776.           showed = TRUE;
  2777.           fprintf(stderr,"\tlabel %d \"%s\" at %g,%g,%g ",
  2778.                 this_label->tag, this_label->text, 
  2779.                 this_label->x, this_label->y, this_label->z);
  2780.           switch(this_label->pos) {
  2781.              case LEFT : {
  2782.                 fprintf(stderr,"left");
  2783.                 break;
  2784.              }
  2785.              case CENTRE : {
  2786.                 fprintf(stderr,"centre");
  2787.                 break;
  2788.              }
  2789.              case RIGHT : {
  2790.                 fprintf(stderr,"right");
  2791.                 break;
  2792.              }
  2793.           }
  2794.           fputc('\n',stderr);
  2795.        }
  2796.     }
  2797.     if (tag > 0 && !showed)
  2798.      int_error("label not found", c_token);
  2799. }
  2800. #endif
  2801.  
  2802. #ifdef THINK_C_2
  2803. static void
  2804. show_arrow(tag)
  2805.     int tag;                /* 0 means show all */
  2806. {
  2807.     struct arrow_def *this_arrow;
  2808.     TBOOLEAN showed = FALSE;
  2809.  
  2810.     for (this_arrow = first_arrow; this_arrow != NULL;
  2811.         this_arrow = this_arrow->next) {
  2812.        if (tag == 0 || tag == this_arrow->tag) {
  2813.           showed = TRUE;
  2814.           fprintf(stderr,"\tarrow %d from %g,%g,%g to %g,%g,%g%s\n",
  2815.                 this_arrow->tag, 
  2816.                 this_arrow->sx, this_arrow->sy, this_arrow->sz,
  2817.                 this_arrow->ex, this_arrow->ey, this_arrow->ez,
  2818.                 this_arrow->head ? "" : " (nohead)");
  2819.        }
  2820.     }
  2821.     if (tag > 0 && !showed)
  2822.      int_error("arrow not found", c_token);
  2823. }
  2824. #endif
  2825.  
  2826. #ifdef THINK_C_2
  2827. static void
  2828. show_grid()
  2829. {
  2830.     fprintf(stderr,"\tgrid is %s\n",(grid)? "ON" : "OFF");
  2831. }
  2832. #endif
  2833.  
  2834. #ifdef THINK_C_2
  2835. static void
  2836. show_key()
  2837. {
  2838.     switch (key) {
  2839.         case -1 : 
  2840.             fprintf(stderr,"\tkey is ON\n");
  2841.             break;
  2842.         case 0 :
  2843.             fprintf(stderr,"\tkey is OFF\n");
  2844.             break;
  2845.         case 1 :
  2846.             fprintf(stderr,"\tkey is at %g,%g,%g\n",key_x,key_y,key_z);
  2847.             break;
  2848.     }
  2849. }
  2850. #endif
  2851.  
  2852. #ifdef THINK_C_2
  2853. static void
  2854. show_parametric()
  2855. {
  2856.     fprintf(stderr,"\tparametric is %s\n",(parametric)? "ON" : "OFF");
  2857. }
  2858. #endif
  2859.  
  2860. #ifdef THINK_C_2
  2861. static void
  2862. show_polar()
  2863. {
  2864.     fprintf(stderr,"\tpolar is %s\n",(polar)? "ON" : "OFF");
  2865. }
  2866. #endif
  2867.  
  2868. #ifdef THINK_C_2
  2869. static void
  2870. show_angles()
  2871. {
  2872.     fprintf(stderr,"\tAngles are in ");
  2873.     switch (angles_format) {
  2874.         case ANGLES_RADIANS:
  2875.             fprintf(stderr, "radians\n");
  2876.         break;
  2877.         case ANGLES_DEGREES:
  2878.             fprintf(stderr, "degrees\n");
  2879.         break;
  2880.     }
  2881. }
  2882. #endif
  2883.  
  2884. #ifdef THINK_C_2
  2885. static void
  2886. show_tics(showx, showy, showz)
  2887.     TBOOLEAN showx, showy, showz;
  2888. {
  2889.     fprintf(stderr,"\ttics are %s, ",(tic_in)? "IN" : "OUT");
  2890.     fprintf(stderr,"\tticslevel is %g\n",ticslevel);
  2891.  
  2892.     if (showx)
  2893.      show_ticdef(xtics, 'x', &xticdef);
  2894.     if (showy)
  2895.      show_ticdef(ytics, 'y', &yticdef);
  2896.     if (showz)
  2897.      show_ticdef(ztics, 'z', &zticdef);
  2898.     screen_ok = FALSE;
  2899. }
  2900. #endif
  2901.  
  2902. #ifdef THINK_C_2
  2903. /* called by show_tics */
  2904. static void
  2905. show_ticdef(tics, axis, tdef)
  2906.     TBOOLEAN tics;            /* xtics ytics or ztics */
  2907.     char axis;            /* 'x' 'y' or 'z' */
  2908.     struct ticdef *tdef;    /* xticdef yticdef or zticdef */
  2909. {
  2910.     register struct ticmark *t;
  2911.  
  2912.     fprintf(stderr, "\t%c-axis tic labelling is ", axis);
  2913.     if (!tics) {
  2914.        fprintf(stderr, "OFF\n");
  2915.        return;
  2916.     }
  2917.  
  2918.     switch(tdef->type) {
  2919.        case TIC_COMPUTED: {
  2920.           fprintf(stderr, "computed automatically\n");
  2921.           break;
  2922.        }
  2923.         case TIC_MONTH: {
  2924.         fprintf(stderr, "Months computed automatically\n");
  2925.         break;
  2926.        }
  2927.         case TIC_DAY:{
  2928.         fprintf(stderr, "Days computed automatically\n");
  2929.         }
  2930.        case TIC_SERIES: {
  2931.           if (tdef->def.series.end == VERYLARGE)
  2932.             fprintf(stderr, "series from %g by %g\n", 
  2933.                   tdef->def.series.start, tdef->def.series.incr);
  2934.           else
  2935.             fprintf(stderr, "series from %g by %g until %g\n", 
  2936.                   tdef->def.series.start, tdef->def.series.incr, 
  2937.                   tdef->def.series.end);
  2938.           break;
  2939.        }
  2940.        case TIC_USER: {
  2941.           fprintf(stderr, "list (");
  2942.           for (t = tdef->def.user; t != NULL; t=t->next) {
  2943.              if (t->label)
  2944.                fprintf(stderr, "\"%s\" ", t->label);
  2945.              if (t->next)
  2946.                fprintf(stderr, "%g, ", t->position);
  2947.              else
  2948.                fprintf(stderr, "%g", t->position);
  2949.           }
  2950.           fprintf(stderr, ")\n");
  2951.           break;
  2952.        }
  2953.        default: {
  2954.           int_error("unknown ticdef type in show_ticdef()", NO_CARET);
  2955.           /* NOTREACHED */
  2956.        }
  2957.     }
  2958. }
  2959. #endif
  2960.  
  2961. #ifdef THINK_C_2
  2962. static void
  2963. show_time()
  2964. {
  2965.     fprintf(stderr,"\ttime is %s, offset at %d, %d\n",
  2966.         (timedate)? "ON" : "OFF",
  2967.         time_xoffset,time_yoffset);
  2968. }
  2969. #endif
  2970.  
  2971. #ifdef THINK_C_2
  2972. static void
  2973. show_term()
  2974. {
  2975.     fprintf(stderr,"\tterminal type is %s %s\n",
  2976.         term_tbl[term].name, term_options);
  2977. }
  2978. #endif
  2979.  
  2980. #ifdef THINK_C_2
  2981. static void
  2982. show_plot()
  2983. {
  2984.     fprintf(stderr,"\tlast plot command was: %s\n",replot_line);
  2985. }
  2986. #endif
  2987.  
  2988. #ifdef THINK_C_2
  2989. static void
  2990. show_autoscale()
  2991. {
  2992.     fprintf(stderr,"\tautoscaling is ");
  2993.     if (parametric)
  2994.         if (is_3d_plot)
  2995.             fprintf(stderr,"\tt: %s, ",(autoscale_t)? "ON" : "OFF");
  2996.         else
  2997.             fprintf(stderr,"\tu: %s, v: %s, ",
  2998.                         (autoscale_u)? "ON" : "OFF",
  2999.                         (autoscale_v)? "ON" : "OFF");
  3000.     else fprintf(stderr,"\t");
  3001.  
  3002.     if (polar) fprintf(stderr,"r: %s, ",(autoscale_r)? "ON" : "OFF");
  3003.     fprintf(stderr,"x: %s, ",(autoscale_x)? "ON" : "OFF");
  3004.     fprintf(stderr,"y: %s, ",(autoscale_y)? "ON" : "OFF");
  3005.     fprintf(stderr,"z: %s\n",(autoscale_z)? "ON" : "OFF");
  3006. }
  3007. #endif
  3008.  
  3009. #ifdef THINK_C_2
  3010. static void
  3011. show_clip()
  3012. {
  3013.     fprintf(stderr,"\tpoint clip is %s\n",(clip_points)? "ON" : "OFF");
  3014.  
  3015.     if (clip_lines1)
  3016.       fprintf(stderr,
  3017.          "\tdrawing and clipping lines between inrange and outrange points\n");
  3018.     else
  3019.       fprintf(stderr,
  3020.          "\tnot drawing lines between inrange and outrange points\n");
  3021.  
  3022.     if (clip_lines2)
  3023.       fprintf(stderr,
  3024.          "\tdrawing and clipping lines between two outrange points\n");
  3025.     else
  3026.       fprintf(stderr,
  3027.          "\tnot drawing lines between two outrange points\n");
  3028. }
  3029. #endif
  3030.  
  3031. #ifdef THINK_C_2
  3032. static void
  3033. show_mapping()
  3034. {
  3035.     fprintf(stderr,"\tmapping for 3-d data is ");
  3036.  
  3037.     switch (mapping3d) {
  3038.         case MAP3D_CARTESIAN:
  3039.             fprintf(stderr,"cartesian\n");
  3040.             break;
  3041.         case MAP3D_SPHERICAL:
  3042.             fprintf(stderr,"spherical\n");
  3043.             break;
  3044.         case MAP3D_CYLINDRICAL:
  3045.             fprintf(stderr,"cylindrical\n");
  3046.             break;
  3047.     }
  3048. }
  3049. #endif
  3050.  
  3051. #ifdef THINK_C_2
  3052. static void
  3053. show_contour()
  3054. {
  3055.     fprintf(stderr,"\tcontour for surfaces are %s",
  3056.         (draw_contour)? "drawn" : "not drawn\n");
  3057.  
  3058.     if (draw_contour) {
  3059.             fprintf(stderr, " in %d levels on ", contour_levels);
  3060.         switch (draw_contour) {
  3061.             case CONTOUR_BASE:
  3062.                 fprintf(stderr,"grid base\n");
  3063.                 break;
  3064.             case CONTOUR_SRF:
  3065.                 fprintf(stderr,"surface\n");
  3066.                 break;
  3067.             case CONTOUR_BOTH:
  3068.                 fprintf(stderr,"grid base and surface\n");
  3069.                 break;
  3070.         }
  3071.         switch (contour_kind) {
  3072.             case CONTOUR_KIND_LINEAR:
  3073.                 fprintf(stderr,"\t\tas linear segments\n");
  3074.                 break;
  3075.             case CONTOUR_KIND_CUBIC_SPL:
  3076.                 fprintf(stderr,"\t\tas cubic spline interpolation segments with %d pts\n",
  3077.                     contour_pts);
  3078.                 break;
  3079.             case CONTOUR_KIND_BSPLINE:
  3080.                 fprintf(stderr,"\t\tas bspline approximation segments of order %d with %d pts\n",
  3081.                     contour_order, contour_pts);
  3082.                 break;
  3083.         }
  3084.         switch (levels_kind) {
  3085.             int i;
  3086.             case LEVELS_AUTO:
  3087.                 fprintf(stderr,"\t\t%d automatic levels\n", contour_levels);
  3088.                 break;
  3089.             case LEVELS_DISCRETE:
  3090.                 fprintf(stderr,"\t\t%d discrete levels at ", contour_levels);
  3091.                         fprintf(stderr, "%g", levels_list[0]);
  3092.                 for(i = 1; i < contour_levels; i++)
  3093.                     fprintf(stderr,",%g ", levels_list[i]);
  3094.                 fprintf(stderr,"\n");
  3095.                 break;
  3096.             case LEVELS_INCREMENTAL:
  3097.                 fprintf(stderr,"\t\t%d incremental levels starting at %g, step %g, end %g\n",
  3098.                     contour_levels, levels_list[0], levels_list[1],
  3099.                     levels_list[0]+contour_levels*levels_list[1]);
  3100.                 break;
  3101.         }
  3102.         fprintf(stderr,"\t\tcontour line types are %s\n", label_contours ? "varied" : "all the same");
  3103.     }
  3104. }
  3105. #endif
  3106.  
  3107. #ifdef THINK_C_2
  3108. static void
  3109. show_format()
  3110. {
  3111.     fprintf(stderr, "\ttic format is x-axis: \"%s\", y-axis: \"%s\", z-axis: \"%s\"\n",
  3112.         xformat, yformat, zformat);
  3113. }
  3114. #endif
  3115.  
  3116. #ifdef THINK_C_2
  3117. static void
  3118. show_logscale()
  3119. {
  3120.     if (is_log_x) {
  3121.         fprintf(stderr,"\tlogscaling x (base %g)", base_log_x);
  3122.         if (is_log_y && is_log_z)
  3123.             fprintf(stderr,", y (base %g) and z (base %g)\n",
  3124.                 base_log_y, base_log_z);
  3125.         else if (is_log_y)
  3126.             fprintf(stderr," and y (base %g)\n", base_log_y);
  3127.         else if (is_log_z)
  3128.             fprintf(stderr," and z (base %g)\n", base_log_z);
  3129.         else
  3130.             fprintf(stderr," only\n");
  3131.     } else if (is_log_y) {
  3132.         fprintf(stderr,"\tlogscaling y (base %g)", base_log_y);
  3133.         if (is_log_z)
  3134.             fprintf(stderr," and z (base %g)\n", base_log_z);
  3135.         else
  3136.             fprintf(stderr," only\n");
  3137.     } else if (is_log_z) {
  3138.         fprintf(stderr,"\tlogscaling z (base %g) only\n", base_log_z);
  3139.     } else {
  3140.         fprintf(stderr,"\tno logscaling\n");
  3141.     }
  3142. }
  3143. #endif
  3144.  
  3145. #ifdef THINK_C_2
  3146. static void
  3147. show_variables()
  3148. {
  3149. register struct udvt_entry *udv = first_udv;
  3150. int len;
  3151.  
  3152.     fprintf(stderr,"\n\tVariables:\n");
  3153.     while (udv) {
  3154.          len = instring(udv->udv_name, ' ');
  3155.         fprintf(stderr,"\t%-*s ",len,udv->udv_name);
  3156.         if (udv->udv_undef)
  3157.             fputs("is undefined\n",stderr);
  3158.         else {
  3159.             fputs("= ",stderr);
  3160.             disp_value(stderr,&(udv->udv_value));
  3161.             (void) putc('\n',stderr);
  3162.         }
  3163.         udv = udv->next_udv;
  3164.     }
  3165. }
  3166. #endif
  3167.  
  3168. #ifdef THINK_C_2
  3169. char *authors[] = {"Thomas Williams","Colin Kelley"}; /* primary */
  3170. void                /* used by plot.c */
  3171. show_version()
  3172. {
  3173. extern char version[];
  3174. extern char patchlevel[];
  3175. extern char date[];
  3176. extern char copyright[];
  3177. extern char bug_email[];
  3178. extern char help_email[];
  3179. int x;
  3180. long time();
  3181.  
  3182.     x = time((long *)NULL) & 1;
  3183.     fprintf(stderr,"\n\t%s\n\t%sversion %s\n",
  3184.         PROGRAM, OS, version); 
  3185.     fprintf(stderr,"\tpatchlevel %s\n",patchlevel);
  3186.      fprintf(stderr, "\tlast modified %s\n", date);
  3187.     fprintf(stderr,"\n\t%s   %s, %s\n", copyright,authors[x],authors[1-x]);
  3188.     fprintf(stderr, "\n\tSend comments and requests for help to %s", help_email);
  3189.     fprintf(stderr, "\n\tSend bugs, suggestions and mods to %s\n", bug_email);
  3190. }
  3191. #endif
  3192.