home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume24 / gnuplot3 / part04 < prev    next >
Text File  |  1991-10-26  |  49KB  |  1,781 lines

  1. Newsgroups: comp.sources.misc
  2. From: gershon%gr@cs.utah.edu (Elber Gershon)
  3. Subject:  v24i026:  gnuplot3 - interactive function plotting utility, Part04/26
  4. Message-ID: <1991Oct26.222204.6282@sparky.imd.sterling.com>
  5. X-Md4-Signature: c3149ff098bc8e28f256ddab05c10cd8
  6. Date: Sat, 26 Oct 1991 22:22:04 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: gershon%gr@cs.utah.edu (Elber Gershon)
  10. Posting-number: Volume 24, Issue 26
  11. Archive-name: gnuplot3/part04
  12. Environment: UNIX, MS-DOS, VMS
  13. Supersedes: gnuplot2: Volume 11, Issue 65-79
  14.  
  15. #!/bin/sh
  16. # this is Part.04 (part 4 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file gnuplot/bitmap.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 4; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping gnuplot/bitmap.c'
  34. else
  35. echo 'x - continuing file gnuplot/bitmap.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'gnuplot/bitmap.c' &&
  37. */
  38. void
  39. b_makebitmap(x, y, planes)
  40. unsigned int x, y, planes;
  41. {
  42. X  register unsigned j;
  43. X  unsigned rows;
  44. X
  45. X  x = 8 * (unsigned int)(x/8.0+0.9);    /* round up to multiple of 8 */
  46. X  y = 8 * (unsigned int)(y/8.0+0.9);    /* round up to multiple of 8 */
  47. X  b_psize = y/8;                    /* size of each plane */
  48. X  rows = b_psize * planes;            /* total number of rows of 8 pixels high */
  49. X  b_xsize = x; b_ysize = y;
  50. X  b_currx = b_curry = 0;
  51. X  b_planes = planes;
  52. X  b_value = 1;
  53. X  b_angle = 0;
  54. X  b_rastermode = 0;
  55. X  /* allocate row pointers */
  56. X  b_p = (bitmap *)alloc( rows * sizeof(pixels *), "bitmap row buffer");
  57. X  bzero(b_p, rows * sizeof(pixels *));
  58. X  for (j = 0; j < rows; j++) {
  59. X    /* allocate bitmap buffers */
  60. X    (*b_p)[j] = (pixels *)alloc(x * sizeof(pixels),(char *)NULL);
  61. X    if ((*b_p)[j] == (pixels *)NULL) {
  62. X        b_freebitmap();  /* free what we have already allocated */
  63. X        int_error("out of memory for bitmap buffer", NO_CARET);
  64. X    }
  65. X    bzero((*b_p)[j], x * sizeof(pixels));
  66. X  }
  67. }
  68. X  
  69. /*
  70. ** free the allocated bitmap
  71. */
  72. void
  73. b_freebitmap()
  74. {
  75. X  int j;
  76. X  unsigned rows;
  77. X
  78. X  rows = b_psize * b_planes;   /* total number of rows of 8 pixels high */
  79. X  for (j = 0; j < rows; j++)
  80. X  {
  81. X    (void) free((char *)(*b_p)[j]);
  82. X  }
  83. X  (void) free((char *)b_p);
  84. X  b_p = (bitmap *)(NULL);
  85. }
  86. X
  87. /*
  88. ** set pixel at (x,y) with color b_value and dotted mask b_linemask.
  89. */
  90. void
  91. b_setmaskpixel(x,y,value)
  92. unsigned int x,y,value;
  93. {
  94. X    /* dotted line generator */
  95. X    if ((b_linemask>>b_maskcount)&(unsigned int)(1)) {
  96. X        b_setpixel(x,y,value);
  97. X    }
  98. X    b_maskcount= (b_maskcount+1) % 16;
  99. X    b_lastx= x;  /* last pixel set with mask */
  100. X    b_lasty= y;
  101. }
  102. X
  103. /*
  104. ** draw a line from (x1,y1) to (x2,y2)
  105. ** with color b_value and dotted mask b_linemask.
  106. */
  107. void
  108. b_line(x1,y1,x2,y2)
  109. unsigned int x1,y1,x2,y2;
  110. {
  111. int runcount;
  112. int dx,dy;
  113. int xinc,yinc;
  114. unsigned int xplot,yplot;
  115. X
  116. X    runcount=0;
  117. X    dx = abs((int)(x1)-(int)(x2));
  118. X    if (x2>x1)  xinc=  1;
  119. X    if (x2==x1) xinc=  0;
  120. X    if (x2<x1)  xinc= -1;
  121. X    dy = abs((int)(y1)-(int)(y2));
  122. X    if (y2>y1)  yinc=  1;
  123. X    if (y2==y1) yinc=  0;
  124. X    if (y2<y1)  yinc= -1;
  125. X    xplot=x1;
  126. X    yplot=y1;
  127. X    if (dx>dy) {
  128. X        /* iterate x */
  129. X        if ( (b_linemask==0xffff) ||
  130. X            ((xplot!=b_lastx) && (yplot!=b_lasty)) )
  131. X            b_setmaskpixel(xplot,yplot,b_value);
  132. X        while (xplot!=x2) {
  133. X            xplot+=xinc;
  134. X            runcount+=dy;
  135. X            if (runcount>=(dx-runcount)) {
  136. X                yplot+=yinc;
  137. X                runcount-=dx;
  138. X            }
  139. X            b_setmaskpixel(xplot,yplot,b_value);
  140. X        }
  141. X    } else {
  142. X        /* iterate y */
  143. X        if ( (b_linemask==0xffff) ||
  144. X            ((xplot!=b_lastx) && (yplot!=b_lasty)) )
  145. X            b_setmaskpixel(xplot,yplot,b_value);
  146. X        while (yplot!=y2) {
  147. X            yplot+=yinc;
  148. X            runcount+=dx;
  149. X            if (runcount>=(dy-runcount)) {
  150. X                xplot+=xinc;
  151. X                runcount-=dy;
  152. X            }
  153. X            b_setmaskpixel(xplot,yplot,b_value);
  154. X        }
  155. X    }
  156. }
  157. X
  158. /*
  159. ** set character size
  160. */
  161. void
  162. b_charsize(size)
  163. unsigned int size;
  164. {
  165. X    int j;
  166. X    switch(size) {
  167. X        case FNT5X9:
  168. X            b_hchar = FNT5X9_HCHAR;
  169. X            b_hbits = FNT5X9_HBITS;
  170. X            b_vchar = FNT5X9_VCHAR;
  171. X            b_vbits = FNT5X9_VBITS;
  172. X            for (j = 0; j < FNT_CHARS; j++ )
  173. X                b_font[j] = &fnt5x9[j][0];
  174. X            break;
  175. X        case FNT9X17:
  176. X            b_hchar = FNT9X17_HCHAR;
  177. X            b_hbits = FNT9X17_HBITS;
  178. X            b_vchar = FNT9X17_VCHAR;
  179. X            b_vbits = FNT9X17_VBITS;
  180. X            for (j = 0; j < FNT_CHARS; j++ )
  181. X                b_font[j] = &fnt9x17[j][0];
  182. X            break;
  183. X        case FNT13X25:
  184. X            b_hchar = FNT13X25_HCHAR;
  185. X            b_hbits = FNT13X25_HBITS;
  186. X            b_vchar = FNT13X25_VCHAR;
  187. X            b_vbits = FNT13X25_VBITS;
  188. X            for (j = 0; j < FNT_CHARS; j++ )
  189. X                b_font[j] = &fnt13x25[j][0];
  190. X            break;
  191. X        default:
  192. X            int_error("Unknown character size",NO_CARET);
  193. X    }
  194. }
  195. X
  196. X
  197. /*
  198. ** put characater c at (x,y) rotated by angle with color b_value.
  199. */
  200. void
  201. b_putc(x,y,c,angle)
  202. unsigned int x,y;
  203. char c;
  204. unsigned int angle;
  205. {
  206. X    unsigned int i, j, k;
  207. X    char_row fc;
  208. X
  209. X    j = c - ' ';
  210. X    for ( i = 0; i < b_vbits; i++ ) {
  211. X        fc = *( b_font[j] + i );
  212. X        if ( c == '_' ) {    /* treat underline specially */
  213. X            if ( fc  ) {    /* this this the underline row ? *?
  214. X                /* draw the under line for the full h_char width */
  215. X                for ( k = ( b_hbits - b_hchar )/2;
  216. X                    k < ( b_hbits + b_hchar )/2; k++ ) {
  217. X                    switch(angle) {
  218. X                        case 0 : b_setpixel(x+k+1,y+i,b_value);
  219. X                            break;
  220. X                        case 1 : b_setpixel(x-i,y+k+1,b_value);
  221. X                            break;
  222. X                    }
  223. X                }
  224. X            }
  225. X        }
  226. X        else {
  227. X            /* draw character */
  228. X            for ( k = 0; k < b_hbits; k++ ) {
  229. X                if ( ( fc >> k ) & 1 ) {
  230. X                    switch(angle) {
  231. X                        case 0 : b_setpixel(x+k+1,y+i,b_value);
  232. X                            break;
  233. X                        case 1 : b_setpixel(x-i,y+k+1,b_value);
  234. X                            break;
  235. X                    }
  236. X                }
  237. X            }
  238. X        }
  239. X    }
  240. }
  241. X
  242. X
  243. /*
  244. ** set b_linemask to b_pattern[linetype]
  245. */
  246. int
  247. b_setlinetype(linetype)
  248. int linetype;
  249. {
  250. X    if (linetype>=7)
  251. X        linetype %= 7;
  252. X    b_linemask = b_pattern[linetype+2];
  253. X    b_maskcount=0;
  254. }
  255. X
  256. /*
  257. ** set b_value to value
  258. */
  259. void
  260. b_setvalue(value)
  261. unsigned int value;
  262. {
  263. X    b_value = value;
  264. }
  265. X
  266. /*
  267. ** move to (x,y)
  268. */
  269. int
  270. b_move(x, y)
  271. unsigned int x, y;
  272. {
  273. X  b_currx = x;
  274. X  b_curry = y;
  275. }
  276. X
  277. /*
  278. ** draw to (x,y) with color b_value
  279. */
  280. int
  281. b_vector(x, y)
  282. unsigned int x, y;
  283. {
  284. X  b_line(b_currx, b_curry, x, y);
  285. X  b_currx = x;
  286. X  b_curry = y;
  287. }
  288. X
  289. X
  290. /*
  291. ** put text str at (x,y) with color b_value and rotation b_angle
  292. */
  293. int
  294. b_put_text(x,y,str)
  295. unsigned int x, y;
  296. char *str;
  297. {
  298. X    if (b_angle == 1)
  299. X        x += b_vchar/2;
  300. X    else
  301. X        y -= b_vchar/2;
  302. X   switch (b_angle) {
  303. X      case 0:
  304. X     for (; *str; ++str, x += b_hchar)
  305. X        b_putc (x, y, *str, b_angle);
  306. X                    break;
  307. X      case 1:
  308. X     for (; *str; ++str, y += b_hchar)
  309. X        b_putc (x, y, *str, b_angle);
  310. X                    break;
  311. X    }
  312. }
  313. X
  314. X
  315. int
  316. b_text_angle(ang)
  317. int ang;
  318. {
  319. X    b_angle=(unsigned int)ang;
  320. X    return TRUE;
  321. }
  322. SHAR_EOF
  323. echo 'File gnuplot/bitmap.c is complete' &&
  324. chmod 0666 gnuplot/bitmap.c ||
  325. echo 'restore of gnuplot/bitmap.c failed'
  326. Wc_c="`wc -c < 'gnuplot/bitmap.c'`"
  327. test 51656 -eq "$Wc_c" ||
  328.     echo 'gnuplot/bitmap.c: original size 51656, current size' "$Wc_c"
  329. rm -f _shar_wnt_.tmp
  330. fi
  331. # ============= gnuplot/bitmap.h ==============
  332. if test -f 'gnuplot/bitmap.h' -a X"$1" != X"-c"; then
  333.     echo 'x - skipping gnuplot/bitmap.h (File already exists)'
  334.     rm -f _shar_wnt_.tmp
  335. else
  336. > _shar_wnt_.tmp
  337. echo 'x - extracting gnuplot/bitmap.h (Text)'
  338. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/bitmap.h' &&
  339. /* bitmap.h */
  340. X
  341. /* allow up to 16 bit width for character array */
  342. typedef unsigned int char_row;
  343. typedef char_row * char_box;
  344. X
  345. #define FNT_CHARS   96      /* Number of characters in the font set */
  346. X
  347. #define FNT5X9 0
  348. #define FNT5X9_VCHAR 11 /* vertical spacing between characters */
  349. #define FNT5X9_VBITS 9 /* actual number of rows of bits per char */
  350. #define FNT5X9_HCHAR 7 /* horizontal spacing between characters */
  351. #define FNT5X9_HBITS 5 /* actual number of bits per row per char */
  352. extern char_row fnt5x9[FNT_CHARS][FNT5X9_VBITS];
  353. X
  354. #define FNT9X17 1
  355. #define FNT9X17_VCHAR 21 /* vertical spacing between characters */
  356. #define FNT9X17_VBITS 17 /* actual number of rows of bits per char */
  357. #define FNT9X17_HCHAR 13 /* horizontal spacing between characters */
  358. #define FNT9X17_HBITS 9 /* actual number of bits per row per char */
  359. extern char_row fnt9x17[FNT_CHARS][FNT9X17_VBITS];
  360. X
  361. #define FNT13X25 2
  362. #define FNT13X25_VCHAR 31 /* vertical spacing between characters */
  363. #define FNT13X25_VBITS 25 /* actual number of rows of bits per char */
  364. #define FNT13X25_HCHAR 19 /* horizontal spacing between characters */
  365. #define FNT13X25_HBITS 13 /* actual number of bits per row per char */
  366. extern char_row fnt13x25[FNT_CHARS][FNT13X25_VBITS];
  367. X
  368. X
  369. typedef unsigned char pixels;  /* the type of one set of 8 pixels in bitmap */
  370. typedef pixels *bitmap[];  /* the bitmap */
  371. X
  372. extern bitmap *b_p;                        /* global pointer to bitmap */
  373. extern unsigned int b_currx, b_curry;    /* the current coordinates */
  374. extern unsigned int b_xsize, b_ysize;    /* the size of the bitmap */
  375. extern unsigned int b_planes;            /* number of color planes */
  376. extern unsigned int b_psize;            /* size of each plane */
  377. extern unsigned int b_rastermode;        /* raster mode rotates -90deg */
  378. extern unsigned int b_linemask;            /* 16 bit mask for dotted lines */
  379. extern unsigned int b_value;            /* colour of lines */
  380. extern unsigned int b_hchar;            /* width of characters */
  381. extern unsigned int b_hbits;            /* actual bits in char horizontally */
  382. extern unsigned int b_vchar;            /* height of characters */
  383. extern unsigned int b_vbits;            /* actual bits in char vertically */
  384. extern unsigned int b_angle;            /* rotation of text */
  385. extern char_box b_font[FNT_CHARS];        /* the current font */
  386. extern unsigned int b_pattern[];
  387. extern int b_maskcount;
  388. extern unsigned int b_lastx, b_lasty;    /* last pixel set - used by b_line */
  389. X
  390. X
  391. extern void b_makebitmap();
  392. extern void b_freebitmap();
  393. extern void b_setpixel();
  394. extern unsigned int b_getpixel();
  395. extern void b_line();
  396. extern void b_setmaskpixel();
  397. extern void b_putc();
  398. extern void b_charsize();
  399. extern void b_setvalue();
  400. X
  401. extern int b_setlinetype();
  402. extern int b_move();
  403. extern int b_vector();
  404. extern int b_put_text();
  405. extern int b_text_angle();
  406. X
  407. SHAR_EOF
  408. chmod 0666 gnuplot/bitmap.h ||
  409. echo 'restore of gnuplot/bitmap.h failed'
  410. Wc_c="`wc -c < 'gnuplot/bitmap.h'`"
  411. test 2726 -eq "$Wc_c" ||
  412.     echo 'gnuplot/bitmap.h: original size 2726, current size' "$Wc_c"
  413. rm -f _shar_wnt_.tmp
  414. fi
  415. # ============= gnuplot/buildvms.com ==============
  416. if test -f 'gnuplot/buildvms.com' -a X"$1" != X"-c"; then
  417.     echo 'x - skipping gnuplot/buildvms.com (File already exists)'
  418.     rm -f _shar_wnt_.tmp
  419. else
  420. > _shar_wnt_.tmp
  421. echo 'x - extracting gnuplot/buildvms.com (Text)'
  422. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/buildvms.com' &&
  423. $ ! buildvms.com  (Command file to compile/link gnuplot and doc2hlp)
  424. $ CFLAGS = "/NOOP/define=(NOGAMMA,MEMSET)"
  425. $ !TERMFLAGS = "/define=()"
  426. $ TERMFLAGS = ""
  427. $ set verify
  428. $ cc 'CFLAGS' bitmap.c
  429. $ cc 'CFLAGS' command.c
  430. $ cc 'CFLAGS' contour.c
  431. $ cc 'CFLAGS' eval.c
  432. $ cc 'CFLAGS' graphics.c
  433. $ cc 'CFLAGS' graph3d.c
  434. $ cc 'CFLAGS' internal.c
  435. $ cc 'CFLAGS' misc.c
  436. $ cc 'CFLAGS' parse.c
  437. $ cc 'CFLAGS' plot.c
  438. $ cc 'CFLAGS' scanner.c
  439. $ cc 'CFLAGS' setshow.c
  440. $ cc 'CFLAGS' standard.c
  441. $ cc 'CFLAGS' 'TERMFLAGS' term.c
  442. $ cc 'CFLAGS' util.c
  443. $ cc 'CFLAGS' version.c
  444. $ link /exe=gnuplot -
  445. X   bitmap.obj,command.obj,contour.obj,eval.obj,graphics.obj,graph3d.obj, -
  446. X   internal.obj,misc.obj,parse.obj,plot.obj,scanner.obj,setshow.obj, -
  447. X   standard.obj,term.obj,util.obj,version.obj ,linkopt.vms/opt
  448. $ cc [.docs]doc2hlp.c
  449. $ link doc2hlp,linkopt.vms/opt
  450. $ @[.docs]doc2hlp.com
  451. $ library/create/help gnuplot.hlb gnuplot.hlp
  452. $ set noverify
  453. SHAR_EOF
  454. chmod 0644 gnuplot/buildvms.com ||
  455. echo 'restore of gnuplot/buildvms.com failed'
  456. Wc_c="`wc -c < 'gnuplot/buildvms.com'`"
  457. test 918 -eq "$Wc_c" ||
  458.     echo 'gnuplot/buildvms.com: original size 918, current size' "$Wc_c"
  459. rm -f _shar_wnt_.tmp
  460. fi
  461. # ============= gnuplot/misc.c ==============
  462. if test -f 'gnuplot/misc.c' -a X"$1" != X"-c"; then
  463.     echo 'x - skipping gnuplot/misc.c (File already exists)'
  464.     rm -f _shar_wnt_.tmp
  465. else
  466. > _shar_wnt_.tmp
  467. echo 'x - extracting gnuplot/misc.c (Text)'
  468. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/misc.c' &&
  469. /* GNUPLOT - misc.c */
  470. /*
  471. X * Copyright (C) 1986, 1987, 1990, 1991   Thomas Williams, Colin Kelley
  472. X *
  473. X * Permission to use, copy, and distribute this software and its
  474. X * documentation for any purpose with or without fee is hereby granted, 
  475. X * provided that the above copyright notice appear in all copies and 
  476. X * that both that copyright notice and this permission notice appear 
  477. X * in supporting documentation.
  478. X *
  479. X * Permission to modify the software is granted, but not the right to
  480. X * distribute the modified code.  Modifications are to be distributed 
  481. X * as patches to released version.
  482. X *  
  483. X * This software is provided "as is" without express or implied warranty.
  484. X * 
  485. X *
  486. X * AUTHORS
  487. X * 
  488. X *   Original Software:
  489. X *     Thomas Williams,  Colin Kelley.
  490. X * 
  491. X *   Gnuplot 2.0 additions:
  492. X *       Russell Lang, Dave Kotz, John Campbell.
  493. X *
  494. X *   Gnuplot 3.0 additions:
  495. X *       Gershon Elber and many others.
  496. X * 
  497. X * Send your comments or suggestions to 
  498. X *  pixar!info-gnuplot@sun.com.
  499. X * This is a mailing list; to join it send a note to 
  500. X *  pixar!info-gnuplot-request@sun.com.  
  501. X * Send bug reports to
  502. X *  pixar!bug-gnuplot@sun.com.
  503. X */
  504. X
  505. #include <stdio.h>
  506. #include <math.h>
  507. #include "plot.h"
  508. #include "setshow.h"
  509. #include "help.h"
  510. #ifdef __TURBOC__
  511. #include <graphics.h>
  512. #endif
  513. X
  514. #ifndef _IBMR2
  515. extern char *malloc();
  516. extern char *realloc();
  517. #endif
  518. X
  519. extern int c_token;
  520. extern char replot_line[];
  521. extern struct at_type at;
  522. extern struct ft_entry ft[];
  523. extern struct udft_entry *first_udf;
  524. extern struct udvt_entry *first_udv;
  525. X
  526. extern struct at_type *temp_at();
  527. X
  528. extern BOOLEAN interactive;
  529. extern char *infile_name;
  530. extern int inline_num;
  531. X
  532. /* State information for load_file(), to recover from errors
  533. X * and properly handle recursive load_file calls
  534. X */
  535. typedef struct lf_state_struct LFS;
  536. struct lf_state_struct {
  537. X    FILE *fp;                /* file pointer for load file */
  538. X    char *name;            /* name of file */
  539. X    BOOLEAN interactive;        /* value of interactive flag on entry */
  540. X    int inline_num;            /* inline_num on entry */
  541. X    LFS *prev;                /* defines a stack */
  542. } *lf_head = NULL;            /* NULL if not in load_file */
  543. X
  544. static BOOLEAN lf_pop();
  545. static void lf_push();
  546. X
  547. /*
  548. X * instead of <strings.h>
  549. X */
  550. extern int strcmp();
  551. X
  552. /*
  553. X * Turbo C realloc does not do the right thing. Here is what it should do.
  554. X */
  555. #ifdef __TURBOC__
  556. char *realloc(p, new_size)
  557. X          void *p;
  558. X          size_t new_size;
  559. {
  560. X    void *new_p = alloc(new_size, "TC realloc");
  561. X
  562. X    /* Note p may have less than new_size bytes but in this unprotected
  563. X     * environment this will work.
  564. X     */
  565. X    memcpy(new_p, p, new_size);
  566. X    free(p);
  567. X    return new_p;
  568. }
  569. #endif /* __TURBOC__ */
  570. X
  571. /*
  572. X * cp_alloc() allocates a curve_points structure that can hold 'num'
  573. X * points.
  574. X */
  575. struct curve_points *
  576. cp_alloc(num)
  577. X    int num;
  578. {
  579. X    struct curve_points *cp;
  580. X    cp = (struct curve_points *) alloc(sizeof(struct curve_points), "curve");
  581. X    cp->p_max = (num >= 0 ? num : 0);
  582. X    if (num > 0) {
  583. X       cp->points = (struct coordinate *)
  584. X        alloc(num * sizeof(struct coordinate), "curve points");
  585. X    } else
  586. X       cp->points = (struct coordinate *) NULL;
  587. X    cp->next_cp = NULL;
  588. X    cp->title = NULL;
  589. X    return(cp);
  590. }
  591. X
  592. X
  593. /*
  594. X * cp_extend() reallocates a curve_points structure to hold "num"
  595. X * points. This will either expand or shrink the storage.
  596. X */
  597. cp_extend(cp, num)
  598. X    struct curve_points *cp;
  599. X    int num;
  600. {
  601. X    struct coordinate *new;
  602. X
  603. #ifdef PC
  604. X    /* Make sure we do not allocate more than 64k (8088 architecture...)
  605. X     * in msdos since we can not address more. Leave some bytes for malloc
  606. X     * maintainance.
  607. X     */
  608. X    if (num > 65500L / sizeof(struct coordinate))
  609. X    int_error("Can not allocate more than 64k in msdos", NO_CARET);
  610. #endif /* PC */
  611. X
  612. X    if (num == cp->p_max) return;
  613. X
  614. X    if (num > 0) {
  615. X       if (cp->points == NULL) {
  616. X          cp->points = (struct coordinate *)
  617. X            alloc(num * sizeof(struct coordinate), "curve points");
  618. X       } else {
  619. X          new = (struct coordinate *)
  620. X            realloc(cp->points, num * sizeof(struct coordinate));
  621. X          if (new == (struct coordinate *) NULL) {
  622. X             int_error("No memory available for expanding curve points",
  623. X                     NO_CARET);
  624. X             /* NOTREACHED */
  625. X          }
  626. X          cp->points = new;
  627. X       }
  628. X       cp->p_max = num;
  629. X    } else {
  630. X       if (cp->points != (struct coordinate *) NULL)
  631. X        free(cp->points);
  632. X       cp->points = (struct coordinate *) NULL;
  633. X       cp->p_max = 0;
  634. X    }
  635. }
  636. X
  637. /*
  638. X * cp_free() releases any memory which was previously malloc()'d to hold
  639. X *   curve points (and recursively down the linked list).
  640. X */
  641. cp_free(cp)
  642. struct curve_points *cp;
  643. {
  644. X    if (cp) {
  645. X        cp_free(cp->next_cp);
  646. X        if (cp->title)
  647. X            free((char *)cp->title);
  648. X        if (cp->points)
  649. X            free((char *)cp->points);
  650. X        free((char *)cp);
  651. X    }
  652. }
  653. X
  654. /*
  655. X * iso_alloc() allocates a iso_curve structure that can hold 'num'
  656. X * points.
  657. X */
  658. struct iso_curve *
  659. iso_alloc(num)
  660. X    int num;
  661. {
  662. X    struct iso_curve *ip;
  663. X    ip = (struct iso_curve *) alloc(sizeof(struct iso_curve), "iso curve");
  664. X    ip->p_max = (num >= 0 ? num : 0);
  665. X    if (num > 0) {
  666. X       ip->points = (struct coordinate *)
  667. X        alloc(num * sizeof(struct coordinate), "iso curve points");
  668. X    } else
  669. X       ip->points = (struct coordinate *) NULL;
  670. X    ip->next = NULL;
  671. X    return(ip);
  672. }
  673. X
  674. /*
  675. X * iso_extend() reallocates a iso_curve structure to hold "num"
  676. X * points. This will either expand or shrink the storage.
  677. X */
  678. iso_extend(ip, num)
  679. X    struct iso_curve *ip;
  680. X    int num;
  681. {
  682. X    struct coordinate *new;
  683. X
  684. X    if (num == ip->p_max) return;
  685. X
  686. #ifdef PC
  687. X    /* Make sure we do not allocate more than 64k (8088 architecture...)
  688. X     * in msdos since we can not address more. Leave some bytes for malloc
  689. X     * maintainance.
  690. X     */
  691. X    if (num > 65500L / sizeof(struct coordinate))
  692. X    int_error("Can not allocate more than 64k in msdos", NO_CARET);
  693. #endif /* PC */
  694. X
  695. X    if (num > 0) {
  696. X       if (ip->points == NULL) {
  697. X          ip->points = (struct coordinate *)
  698. X            alloc(num * sizeof(struct coordinate), "iso curve points");
  699. X       } else {
  700. X          new = (struct coordinate *)
  701. X            realloc(ip->points, num * sizeof(struct coordinate));
  702. X          if (new == (struct coordinate *) NULL) {
  703. X             int_error("No memory available for expanding curve points",
  704. X                     NO_CARET);
  705. X             /* NOTREACHED */
  706. X          }
  707. X          ip->points = new;
  708. X       }
  709. X       ip->p_max = num;
  710. X    } else {
  711. X       if (ip->points != (struct coordinate *) NULL)
  712. X        free(ip->points);
  713. X       ip->points = (struct coordinate *) NULL;
  714. X       ip->p_max = 0;
  715. X    }
  716. }
  717. X
  718. /*
  719. X * iso_free() releases any memory which was previously malloc()'d to hold
  720. X *   iso curve points.
  721. X */
  722. iso_free(ip)
  723. struct iso_curve *ip;
  724. {
  725. X    if (ip) {
  726. X        if (ip->points)
  727. X            free((char *)ip->points);
  728. X        free((char *)ip);
  729. X    }
  730. }
  731. X
  732. /*
  733. X * sp_alloc() allocates a surface_points structure that can hold 'num_iso'
  734. X * iso-curves, each of which 'num_samp' samples.
  735. X * if, however num_iso or num_samp is zero no iso curves are allocated.
  736. X */
  737. struct surface_points *
  738. sp_alloc(num_samp,num_iso)
  739. X    int num_samp,num_iso;
  740. {
  741. X    struct surface_points *sp;
  742. X
  743. X    sp = (struct surface_points *) alloc(sizeof(struct surface_points), "surface");
  744. X    sp->next_sp = NULL;
  745. X    sp->title = NULL;
  746. X    sp->contours = NULL;
  747. X    sp->iso_crvs = NULL;
  748. X    sp->num_iso_read = 0;
  749. X
  750. X    if (num_iso > 0 && num_samp > 0) {
  751. X    int i;
  752. X    struct iso_curve *icrv;
  753. X
  754. X    for (i = 0; i < num_iso; i++) {
  755. X        icrv = iso_alloc(num_samp);
  756. X        icrv->next = sp->iso_crvs;
  757. X        sp->iso_crvs = icrv;
  758. X    }
  759. X    } else
  760. X    sp->iso_crvs = (struct iso_curve *) NULL;
  761. X
  762. X    return(sp);
  763. }
  764. X
  765. /*
  766. X * sp_replace() updates a surface_points structure so it can hold 'num_iso'
  767. X * iso-curves, each of which 'num_samp' samples.
  768. X * if, however num_iso or num_samp is zero no iso curves are allocated.
  769. X */
  770. sp_replace(sp,num_samp,num_iso)
  771. X       struct surface_points *sp;
  772. X       int num_samp,num_iso;
  773. {
  774. X    int i;
  775. X    struct iso_curve *icrv, *icrvs = sp->iso_crvs;
  776. X
  777. X    while ( icrvs ) {
  778. X    icrv = icrvs;
  779. X    icrvs = icrvs->next;
  780. X    iso_free( icrv );
  781. X    }
  782. X    sp->iso_crvs = NULL;
  783. X    
  784. X    if (num_iso > 0 && num_samp > 0) {
  785. X    for (i = 0; i < num_iso; i++) {
  786. X        icrv = iso_alloc(num_samp);
  787. X        icrv->next = sp->iso_crvs;
  788. X        sp->iso_crvs = icrv;
  789. X    }
  790. X    } else
  791. X    sp->iso_crvs = (struct iso_curve *) NULL;
  792. }
  793. X
  794. /*
  795. X * sp_free() releases any memory which was previously malloc()'d to hold
  796. X *   surface points.
  797. X */
  798. sp_free(sp)
  799. struct surface_points *sp;
  800. {
  801. X    if (sp) {
  802. X        sp_free(sp->next_sp);
  803. X        if (sp->title)
  804. X            free((char *)sp->title);
  805. X        if (sp->contours) {
  806. X            struct gnuplot_contours *cntr, *cntrs = sp->contours;
  807. X
  808. X            while (cntrs) {
  809. X                cntr = cntrs;
  810. X                cntrs = cntrs->next;
  811. X                free(cntr->coords);
  812. X                free(cntr);
  813. X            }
  814. X        }
  815. X        if (sp->iso_crvs) {
  816. X            struct iso_curve *icrv, *icrvs = sp->iso_crvs;
  817. X
  818. X            while (icrvs) {
  819. X                icrv = icrvs;
  820. X                icrvs = icrvs->next;
  821. X                iso_free(icrv);
  822. X            }
  823. X        }
  824. X        free((char *)sp);
  825. X    }
  826. }
  827. X
  828. X
  829. X
  830. save_functions(fp)
  831. FILE *fp;
  832. {
  833. register struct udft_entry *udf = first_udf;
  834. X
  835. X    if (fp) {
  836. X        while (udf) {
  837. X            if (udf->definition)
  838. X                fprintf(fp,"%s\n",udf->definition);
  839. X            udf = udf->next_udf;
  840. X        }
  841. X        (void) fclose(fp);
  842. X    } else
  843. X        os_error("Cannot open save file",c_token);            
  844. }
  845. X
  846. X
  847. save_variables(fp)
  848. FILE *fp;
  849. {
  850. register struct udvt_entry *udv = first_udv->next_udv;    /* skip pi */
  851. X
  852. X    if (fp) {
  853. X        while (udv) {
  854. X            if (!udv->udv_undef) {
  855. X                fprintf(fp,"%s = ",udv->udv_name);
  856. X                disp_value(fp,&(udv->udv_value));
  857. X                (void) putc('\n',fp);
  858. X            }
  859. X            udv = udv->next_udv;
  860. X        }
  861. X        (void) fclose(fp);
  862. X    } else
  863. X        os_error("Cannot open save file",c_token);            
  864. }
  865. X
  866. X
  867. save_all(fp)
  868. FILE *fp;
  869. {
  870. register struct udft_entry *udf = first_udf;
  871. register struct udvt_entry *udv = first_udv->next_udv;    /* skip pi */
  872. X
  873. X    if (fp) {
  874. X        save_set_all(fp);
  875. X        while (udf) {
  876. X            if (udf->definition)
  877. X                fprintf(fp,"%s\n",udf->definition);
  878. X            udf = udf->next_udf;
  879. X        }
  880. X        while (udv) {
  881. X            if (!udv->udv_undef) {
  882. X                fprintf(fp,"%s = ",udv->udv_name);
  883. X                disp_value(fp,&(udv->udv_value));
  884. X                (void) putc('\n',fp);
  885. X            }
  886. X            udv = udv->next_udv;
  887. X        }
  888. X        fprintf(fp,"%s\n",replot_line);
  889. X        (void) fclose(fp);
  890. X    } else
  891. X        os_error("Cannot open save file",c_token);            
  892. }
  893. X
  894. X
  895. save_set(fp)
  896. FILE *fp;
  897. {
  898. X    if (fp) {
  899. X        save_set_all(fp);
  900. X        (void) fclose(fp);
  901. X    } else
  902. X        os_error("Cannot open save file",c_token);            
  903. }
  904. X
  905. X
  906. save_set_all(fp)
  907. FILE *fp;
  908. {
  909. struct text_label *this_label;
  910. struct arrow_def *this_arrow;
  911. X    fprintf(fp,"set terminal %s %s\n", term_tbl[term].name, term_options);
  912. X    fprintf(fp,"set output %s\n",strcmp(outstr,"STDOUT")? outstr : "" );
  913. X    fprintf(fp,"set %sclip points\n", (clip_points)? "" : "no");
  914. X    fprintf(fp,"set %sclip one\n", (clip_lines1)? "" : "no");
  915. X    fprintf(fp,"set %sclip two\n", (clip_lines2)? "" : "no");
  916. X    fprintf(fp,"set %sborder\n",draw_border ? "" : "no");
  917. X    fprintf(fp,"set dummy %s,%s\n",dummy_var[0], dummy_var[1]);
  918. X    fprintf(fp,"set format x \"%s\"\n", xformat);
  919. X    fprintf(fp,"set format y \"%s\"\n", yformat);
  920. X    fprintf(fp,"set format z \"%s\"\n", zformat);
  921. X    fprintf(fp,"set %sgrid\n", (grid)? "" : "no");
  922. X    switch (key) {
  923. X        case -1 : 
  924. X            fprintf(fp,"set key\n");
  925. X            break;
  926. X        case 0 :
  927. X            fprintf(fp,"set nokey\n");
  928. X            break;
  929. X        case 1 :
  930. X            fprintf(fp,"set key %g,%g,%g\n",key_x,key_y,key_z);
  931. X            break;
  932. X    }
  933. X    fprintf(fp,"set nolabel\n");
  934. X    for (this_label = first_label; this_label != NULL;
  935. X            this_label = this_label->next) {
  936. X        fprintf(fp,"set label %d \"%s\" at %g,%g,%g ",
  937. X               this_label->tag,
  938. X               this_label->text, this_label->x,
  939. X                         this_label->y,
  940. X                         this_label->z);
  941. X        switch(this_label->pos) {
  942. X            case LEFT : 
  943. X                fprintf(fp,"left");
  944. X                break;
  945. X            case CENTRE :
  946. X                fprintf(fp,"centre");
  947. X                break;
  948. X            case RIGHT :
  949. X                fprintf(fp,"right");
  950. X                break;
  951. X        }
  952. X        fputc('\n',fp);
  953. X    }
  954. X    fprintf(fp,"set noarrow\n");
  955. X    for (this_arrow = first_arrow; this_arrow != NULL;
  956. X            this_arrow = this_arrow->next) {
  957. X        fprintf(fp,"set arrow %d from %g,%g,%g to %g,%g,%g%s\n",
  958. X               this_arrow->tag,
  959. X               this_arrow->sx, this_arrow->sy, this_arrow->sz,
  960. X               this_arrow->ex, this_arrow->ey, this_arrow->ez,
  961. X               this_arrow->head ? "" : " nohead");
  962. X    }
  963. X    fprintf(fp,"set nologscale\n");
  964. X    if (log_x||log_y)
  965. X        fprintf(fp,"set logscale %c%c\n", 
  966. X        log_x ? 'x' : ' ', log_y ? 'y' : ' ');
  967. X    if (log_z) fprintf(fp,"set logscale z\n");
  968. X    fprintf(fp,"set offsets %g, %g, %g, %g\n",loff,roff,toff,boff);
  969. X    fprintf(fp,"set %spolar\n", (polar)? "" : "no");
  970. X    fprintf(fp,"set angles %s\n", (angles_format == ANGLES_RADIANS)?
  971. X                        "radians" : "degrees");
  972. X    fprintf(fp,"set %sparametric\n", (parametric)? "" : "no");
  973. X    fprintf(fp,"set view %g, %g, %g, %g\n",
  974. X        surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
  975. X    fprintf(fp,"set samples %d\n",samples);
  976. X    fprintf(fp,"set isosamples %d\n",iso_samples);
  977. X    fprintf(fp,"set %ssurface\n",(draw_surface) ? "" : "no");
  978. X    fprintf(fp,"set %scontour",(draw_contour) ? "" : "no");
  979. X    switch (draw_contour) {
  980. X        case CONTOUR_NONE: fprintf(fp, "\n"); break;
  981. X        case CONTOUR_BASE: fprintf(fp, " base\n"); break;
  982. X        case CONTOUR_SRF:  fprintf(fp, " surface\n"); break;
  983. X        case CONTOUR_BOTH: fprintf(fp, " both\n"); break;
  984. X    }
  985. X    fprintf(fp,"set cntrparam order %d\n", contour_order);
  986. X    fprintf(fp,"set cntrparam ");
  987. X    switch (contour_kind) {
  988. X        case CONTOUR_KIND_LINEAR:    fprintf(fp, "linear\n"); break;
  989. X        case CONTOUR_KIND_CUBIC_SPL: fprintf(fp, "cubicspline\n"); break;
  990. X        case CONTOUR_KIND_BSPLINE:   fprintf(fp, "bspline\n"); break;
  991. X    }
  992. X    fprintf(fp,"set cntrparam points %d\n", contour_pts);
  993. X    fprintf(fp,"set size %g,%g\n",xsize,ysize);
  994. X    fprintf(fp,"set data style ");
  995. X    switch (data_style) {
  996. X        case LINES: fprintf(fp,"lines\n"); break;
  997. X        case POINTS: fprintf(fp,"points\n"); break;
  998. X        case IMPULSES: fprintf(fp,"impulses\n"); break;
  999. X        case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
  1000. X        case DOTS: fprintf(fp,"dots\n"); break;
  1001. X        case ERRORBARS: fprintf(fp,"errorbars\n"); break;
  1002. X    }
  1003. X    fprintf(fp,"set function style ");
  1004. X    switch (func_style) {
  1005. X        case LINES: fprintf(fp,"lines\n"); break;
  1006. X        case POINTS: fprintf(fp,"points\n"); break;
  1007. X        case IMPULSES: fprintf(fp,"impulses\n"); break;
  1008. X        case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
  1009. X        case DOTS: fprintf(fp,"dots\n"); break;
  1010. X        case ERRORBARS: fprintf(fp,"errorbars\n"); break;
  1011. X    }
  1012. X    fprintf(fp,"set tics %s\n", (tic_in)? "in" : "out");
  1013. X    fprintf(fp,"set ticslevel %g\n", ticslevel);
  1014. X    save_tics(fp, xtics, 'x', &xticdef);
  1015. X    save_tics(fp, ytics, 'y', &yticdef);
  1016. X    save_tics(fp, ztics, 'z', &zticdef);
  1017. X    fprintf(fp,"set title \"%s\" %d,%d\n",title,title_xoffset,title_yoffset);
  1018. X        if (timedate)
  1019. X        fprintf(fp,"set time %d,%d\n",time_xoffset,time_yoffset);
  1020. X    else
  1021. X        fprintf(fp,"set notime\n");
  1022. X     fprintf(fp,"set rrange [%g : %g]\n",rmin,rmax);
  1023. X    fprintf(fp,"set trange [%g : %g]\n",tmin,tmax);
  1024. X    fprintf(fp,"set xlabel \"%s\" %d,%d\n",xlabel,xlabel_xoffset,xlabel_yoffset);
  1025. X    fprintf(fp,"set xrange [%g : %g]\n",xmin,xmax);
  1026. X    fprintf(fp,"set ylabel \"%s\" %d,%d\n",ylabel,ylabel_xoffset,ylabel_yoffset);
  1027. X    fprintf(fp,"set yrange [%g : %g]\n",ymin,ymax);
  1028. X    fprintf(fp,"set zlabel \"%s\" %d,%d\n",zlabel,zlabel_xoffset,zlabel_yoffset);
  1029. X    fprintf(fp,"set zrange [%g : %g]\n",zmin,zmax);
  1030. X    fprintf(fp,"set %s %c\n", 
  1031. X        autoscale_r ? "autoscale" : "noautoscale", 'r');
  1032. X    fprintf(fp,"set %s %c\n", 
  1033. X        autoscale_t ? "autoscale" : "noautoscale", 't');
  1034. X    fprintf(fp,"set %s %c%c\n", 
  1035. X        (autoscale_y||autoscale_x) ? "autoscale" : "noautoscale", 
  1036. X        autoscale_x ? 'x' : ' ', autoscale_y ? 'y' : ' ');
  1037. X    fprintf(fp,"set %s %c\n", 
  1038. X        autoscale_z ? "autoscale" : "noautoscale", 'z');
  1039. X    fprintf(fp,"set zero %g\n",zero);
  1040. }
  1041. X
  1042. save_tics(fp, onoff, axis, tdef)
  1043. X    FILE *fp;
  1044. X    BOOLEAN onoff;
  1045. X    char axis;
  1046. X    struct ticdef *tdef;
  1047. {
  1048. X    if (onoff) {
  1049. X       fprintf(fp,"set %ctics", axis);
  1050. X       switch(tdef->type) {
  1051. X          case TIC_COMPUTED: {
  1052. X             break;
  1053. X          }
  1054. X          case TIC_SERIES: {
  1055. X                 if (tdef->def.series.end >= VERYLARGE)
  1056. X                 fprintf(fp, " %g,%g", tdef->def.series.start,
  1057. X                                        tdef->def.series.incr);
  1058. X                         else
  1059. X                 fprintf(fp, " %g,%g,%g", tdef->def.series.start,
  1060. X                                        tdef->def.series.incr, tdef->def.series.end);
  1061. X             break;
  1062. X          }
  1063. X          case TIC_USER: {
  1064. X             register struct ticmark *t;
  1065. X             fprintf(fp, " (");
  1066. X             for (t = tdef->def.user; t != NULL; t=t->next) {
  1067. X                if (t->label)
  1068. X                  fprintf(fp, "\"%s\" ", t->label);
  1069. X                if (t->next)
  1070. X                  fprintf(fp, "%g, ", t->position);
  1071. X                else
  1072. X                  fprintf(fp, "%g", t->position);
  1073. X             }
  1074. X             fprintf(fp, ")");
  1075. X             break;
  1076. X          } 
  1077. X       }
  1078. X       fprintf(fp, "\n");
  1079. X    } else {
  1080. X       fprintf(fp,"set no%ctics\n", axis);
  1081. X    }
  1082. }
  1083. X
  1084. load_file(fp, name)
  1085. X    FILE *fp;
  1086. X    char *name;
  1087. {
  1088. X    register int len;
  1089. X    extern char input_line[];
  1090. X
  1091. X    int start, left;
  1092. X    int more;
  1093. X    int stop = FALSE;
  1094. X
  1095. X    lf_push(fp);            /* save state for errors and recursion */
  1096. X
  1097. X    if (fp == (FILE *)NULL) {
  1098. X       char errbuf[BUFSIZ];
  1099. X       (void) sprintf(errbuf, "Cannot open load file '%s'", name);
  1100. X       os_error(errbuf, c_token);
  1101. X    } else {
  1102. X       /* go into non-interactive mode during load */
  1103. X       /* will be undone below, or in load_file_error */
  1104. X       interactive = FALSE;
  1105. X       inline_num = 0;
  1106. X       infile_name = name;
  1107. X
  1108. X       while (!stop) {        /* read all commands in file */
  1109. X          /* read one command */
  1110. X          left = MAX_LINE_LEN;
  1111. X          start = 0;
  1112. X          more = TRUE;
  1113. X
  1114. X          while (more) {
  1115. X             if (fgets(&(input_line[start]), left, fp) == NULL) {
  1116. X                stop = TRUE; /* EOF in file */
  1117. X                input_line[start] = '\0';
  1118. X                more = FALSE;    
  1119. X             } else {
  1120. X                inline_num++;
  1121. X                len = strlen(input_line) - 1;
  1122. X                if (input_line[len] == '\n') { /* remove any newline */
  1123. X                    input_line[len] = '\0';
  1124. X                    /* Look, len was 1-1 = 0 before, take care here! */
  1125. X                    if (len > 0) --len;
  1126. X                } else if (len+1 >= left)
  1127. X                  int_error("Input line too long",NO_CARET);
  1128. X                 
  1129. X                if (input_line[len] == '\\') { /* line continuation */
  1130. X                    start = len;
  1131. X                    left  = MAX_LINE_LEN - start; /* left -=len;*/
  1132. X                } else
  1133. X                  more = FALSE;
  1134. X             }
  1135. X          }
  1136. X
  1137. X          if (strlen(input_line) > 0) {
  1138. X             screen_ok = FALSE;    /* make sure command line is
  1139. X                               echoed on error */
  1140. X             do_line();
  1141. X          }
  1142. X       }
  1143. X    }
  1144. X
  1145. X    /* pop state */
  1146. X    (void) lf_pop();        /* also closes file fp */
  1147. }
  1148. X
  1149. /* pop from load_file state stack */
  1150. static BOOLEAN                /* FALSE if stack was empty */
  1151. lf_pop()                    /* called by load_file and load_file_error */
  1152. {
  1153. X    LFS *lf;
  1154. X
  1155. X    if (lf_head == NULL)
  1156. X     return(FALSE);
  1157. X    else {
  1158. X       lf = lf_head;
  1159. X       if (lf->fp != (FILE *)NULL)
  1160. X        (void) fclose(lf->fp);
  1161. X       interactive = lf->interactive;
  1162. X       inline_num = lf->inline_num;
  1163. X       infile_name = lf->name;
  1164. X       lf_head = lf->prev;
  1165. X       free((char *)lf);
  1166. X       return(TRUE);
  1167. X    }
  1168. }
  1169. X
  1170. /* push onto load_file state stack */
  1171. /* essentially, we save information needed to undo the load_file changes */
  1172. static void
  1173. lf_push(fp)            /* called by load_file */
  1174. X    FILE *fp;
  1175. {
  1176. X    LFS *lf;
  1177. X    
  1178. X    lf = (LFS *)alloc(sizeof(LFS), (char *)NULL);
  1179. X    if (lf == (LFS *)NULL) {
  1180. X       if (fp != (FILE *)NULL)
  1181. X        (void) fclose(fp);        /* it won't be otherwise */
  1182. X       int_error("not enough memory to load file", c_token);
  1183. X    }
  1184. X     
  1185. X    lf->fp = fp;            /* save this file pointer */
  1186. X    lf->name = infile_name;    /* save current name */
  1187. X    lf->interactive = interactive;    /* save current state */
  1188. X    lf->inline_num = inline_num; /* save current line number */
  1189. X    lf->prev = lf_head;        /* link to stack */
  1190. X    lf_head = lf;
  1191. }
  1192. X
  1193. load_file_error()            /* called from main */
  1194. {
  1195. X    /* clean up from error in load_file */
  1196. X    /* pop off everything on stack */
  1197. X    while(lf_pop())
  1198. X     ;
  1199. }
  1200. X
  1201. /* find char c in string str; return p such that str[p]==c;
  1202. X * if c not in str then p=strlen(str)
  1203. X */
  1204. int
  1205. instring(str, c)
  1206. X    char *str;
  1207. X    char c;
  1208. {
  1209. X    int pos = 0;
  1210. X
  1211. X    while (str != NULL && *str != '\0' && c != *str) {
  1212. X       str++; 
  1213. X       pos++;
  1214. X    }
  1215. X    return (pos);
  1216. }
  1217. X
  1218. show_functions()
  1219. {
  1220. register struct udft_entry *udf = first_udf;
  1221. X
  1222. X    fprintf(stderr,"\n\tUser-Defined Functions:\n");
  1223. X
  1224. X    while (udf) {
  1225. X        if (udf->definition)
  1226. X            fprintf(stderr,"\t%s\n",udf->definition);
  1227. X        else
  1228. X            fprintf(stderr,"\t%s is undefined\n",udf->udf_name);
  1229. X        udf = udf->next_udf;
  1230. X    }
  1231. }
  1232. X
  1233. X
  1234. show_at()
  1235. {
  1236. X    (void) putc('\n',stderr);
  1237. X    disp_at(temp_at(),0);
  1238. }
  1239. X
  1240. X
  1241. disp_at(curr_at, level)
  1242. struct at_type *curr_at;
  1243. int level;
  1244. {
  1245. register int i, j;
  1246. register union argument *arg;
  1247. X
  1248. X    for (i = 0; i < curr_at->a_count; i++) {
  1249. X        (void) putc('\t',stderr);
  1250. X        for (j = 0; j < level; j++)
  1251. X            (void) putc(' ',stderr);    /* indent */
  1252. X
  1253. X            /* print name of instruction */
  1254. X
  1255. X        fputs(ft[(int)(curr_at->actions[i].index)].f_name,stderr);
  1256. X        arg = &(curr_at->actions[i].arg);
  1257. X
  1258. X            /* now print optional argument */
  1259. X
  1260. X        switch(curr_at->actions[i].index) {
  1261. X          case PUSH:    fprintf(stderr," %s\n", arg->udv_arg->udv_name);
  1262. X                    break;
  1263. X          case PUSHC:    (void) putc(' ',stderr);
  1264. X                    disp_value(stderr,&(arg->v_arg));
  1265. X                    (void) putc('\n',stderr);
  1266. X                    break;
  1267. X          case PUSHD1:    fprintf(stderr," %c dummy\n",
  1268. X                      arg->udf_arg->udf_name[0]);
  1269. X                    break;
  1270. X          case PUSHD2:    fprintf(stderr," %c dummy\n",
  1271. X                      arg->udf_arg->udf_name[1]);
  1272. X                    break;
  1273. X          case CALL:    fprintf(stderr," %s", arg->udf_arg->udf_name);
  1274. X                    if(level < 6) {
  1275. X                    if (arg->udf_arg->at) {
  1276. X                        (void) putc('\n',stderr);
  1277. X                        disp_at(arg->udf_arg->at,level+2); /* recurse! */
  1278. X                    } else
  1279. X                        fputs(" (undefined)\n",stderr);
  1280. X                    }
  1281. X                    break;
  1282. X          case CALL2:    fprintf(stderr," %s", arg->udf_arg->udf_name);
  1283. X                    if(level < 6) {
  1284. X                    if (arg->udf_arg->at) {
  1285. X                        (void) putc('\n',stderr);
  1286. X                        disp_at(arg->udf_arg->at,level+2); /* recurse! */
  1287. X                    } else
  1288. X                        fputs(" (undefined)\n",stderr);
  1289. X                    }
  1290. X                    break;
  1291. X          case JUMP:
  1292. X          case JUMPZ:
  1293. X          case JUMPNZ:
  1294. X          case JTERN:
  1295. X                    fprintf(stderr," +%d\n",arg->j_arg);
  1296. X                    break;
  1297. X          default:
  1298. X                    (void) putc('\n',stderr);
  1299. X        }
  1300. X    }
  1301. }
  1302. X
  1303. X
  1304. /* alloc:
  1305. X * allocate memory 
  1306. X * This is a protected version of malloc. It causes an int_error 
  1307. X * if there is not enough memory, but first it tries FreeHelp() 
  1308. X * to make some room, and tries again. If message is NULL, we 
  1309. X * allow NULL return. Otherwise, we handle the error, using the
  1310. X * message to create the int_error string. Note cp/sp_extend uses realloc,
  1311. X * so it depends on this using malloc().
  1312. X */
  1313. X
  1314. char *
  1315. alloc(size, message)
  1316. X    unsigned int size;                /* # of bytes */
  1317. X    char *message;            /* description of what is being allocated */
  1318. {
  1319. X    char *p;                /* the new allocation */
  1320. X    char errbuf[100];        /* error message string */
  1321. X
  1322. X    p = malloc(size);
  1323. X    if (p == (char *)NULL) {
  1324. #ifndef vms
  1325. X       FreeHelp();            /* out of memory, try to make some room */
  1326. #endif
  1327. X       
  1328. X       p = malloc(size);        /* try again */
  1329. X       if (p == (char *)NULL) {
  1330. X          /* really out of memory */
  1331. X          if (message != NULL) {
  1332. X             (void) sprintf(errbuf, "out of memory for %s", message);
  1333. X             int_error(errbuf, NO_CARET);
  1334. X             /* NOTREACHED */
  1335. X          }
  1336. X          /* else we return NULL */
  1337. X       }
  1338. X    }
  1339. X
  1340. X    return(p);
  1341. }
  1342. SHAR_EOF
  1343. chmod 0644 gnuplot/misc.c ||
  1344. echo 'restore of gnuplot/misc.c failed'
  1345. Wc_c="`wc -c < 'gnuplot/misc.c'`"
  1346. test 22387 -eq "$Wc_c" ||
  1347.     echo 'gnuplot/misc.c: original size 22387, current size' "$Wc_c"
  1348. rm -f _shar_wnt_.tmp
  1349. fi
  1350. # ============= gnuplot/contour.c ==============
  1351. if test -f 'gnuplot/contour.c' -a X"$1" != X"-c"; then
  1352.     echo 'x - skipping gnuplot/contour.c (File already exists)'
  1353.     rm -f _shar_wnt_.tmp
  1354. else
  1355. > _shar_wnt_.tmp
  1356. echo 'x - extracting gnuplot/contour.c (Text)'
  1357. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/contour.c' &&
  1358. /* GNUPLOT - contour.c */
  1359. /*
  1360. X * Copyright (C) 1986, 1987, 1990, 1991   Thomas Williams, Colin Kelley
  1361. X *
  1362. X * Permission to use, copy, and distribute this software and its
  1363. X * documentation for any purpose with or without fee is hereby granted, 
  1364. X * provided that the above copyright notice appear in all copies and 
  1365. X * that both that copyright notice and this permission notice appear 
  1366. X * in supporting documentation.
  1367. X *
  1368. X * Permission to modify the software is granted, but not the right to
  1369. X * distribute the modified code.  Modifications are to be distributed 
  1370. X * as patches to released version.
  1371. X *  
  1372. X * This software is provided "as is" without express or implied warranty.
  1373. X * 
  1374. X *
  1375. X * AUTHORS
  1376. X * 
  1377. X *   Original Software:
  1378. X *       Gershon Elber
  1379. X * 
  1380. X * Send your comments or suggestions to 
  1381. X *  pixar!info-gnuplot@sun.com.
  1382. X * This is a mailing list; to join it send a note to 
  1383. X *  pixar!info-gnuplot-request@sun.com.  
  1384. X * Send bug reports to
  1385. X *  pixar!bug-gnuplot@sun.com.
  1386. X */
  1387. X
  1388. #include <stdio.h>
  1389. #include "plot.h"
  1390. X
  1391. #define DEFAULT_NUM_OF_ZLEVELS  10  /* Some dflt values (setable via flags). */
  1392. #define DEFAULT_NUM_APPROX_PTS  5
  1393. #define DEFAULT_BSPLINE_ORDER  3
  1394. #define MAX_NUM_OF_ZLEVELS      100 /* Some max. values (setable via flags). */
  1395. #define MAX_NUM_APPROX_PTS      100
  1396. #define MAX_BSPLINE_ORDER      10
  1397. X
  1398. #define INTERP_NOTHING   0            /* Kind of interpolations on contours. */
  1399. #define INTERP_CUBIC     1                           /* Cubic spline interp. */
  1400. #define APPROX_BSPLINE   2                         /* Bspline interpolation. */
  1401. X
  1402. #define ACTIVE   1                    /* Status of edges at certain Z level. */
  1403. #define INACTIVE 2
  1404. X
  1405. #define OPEN_CONTOUR     1                                 /* Contour kinds. */
  1406. #define CLOSED_CONTOUR   2
  1407. X
  1408. #define EPSILON  1e-5              /* Used to decide if two float are equal. */
  1409. #define INFINITY 1e10
  1410. X
  1411. #ifndef TRUE
  1412. #define TRUE     -1
  1413. #define FALSE    0
  1414. #endif
  1415. X
  1416. #define DEFAULT_NUM_CONTOURS    10
  1417. #define MAX_POINTS_PER_CNTR     100
  1418. #define SHIFT_Z_EPSILON        0.000301060 /* Dec. change of poly bndry hit.*/
  1419. X
  1420. #define abs(x)  ((x) > 0 ? (x) : (-(x)))
  1421. #define sqr(x)  ((x) * (x))
  1422. X
  1423. typedef double tri_diag[3];         /* Used to allocate the tri-diag matrix. */
  1424. typedef double table_entry[4];           /* Cubic spline interpolation 4 coef. */
  1425. X
  1426. struct vrtx_struct {
  1427. X    double X, Y, Z;                       /* The coordinates of this vertex. */
  1428. X    struct vrtx_struct *next;                             /* To chain lists. */
  1429. };
  1430. X
  1431. struct edge_struct {
  1432. X    struct poly_struct *poly[2];   /* Each edge belongs to up to 2 polygons. */
  1433. X    struct vrtx_struct *vertex[2]; /* The two extreme points of this vertex. */
  1434. X    struct edge_struct *next;                             /* To chain lists. */
  1435. X    int status, /* Status flag to mark edges in scanning at certain Z level. */
  1436. X    boundary;                   /* True if this edge is on the boundary. */
  1437. };
  1438. X
  1439. struct poly_struct {
  1440. X    struct edge_struct *edge[3];           /* As we do triangolation here... */
  1441. X    struct poly_struct *next;                             /* To chain lists. */
  1442. };
  1443. X
  1444. struct cntr_struct {           /* Contours are saved using this struct list. */
  1445. X    double X, Y;                          /* The coordinates of this vertex. */
  1446. X    struct cntr_struct *next;                             /* To chain lists. */
  1447. };
  1448. X
  1449. static int test_boundary;    /* If TRUE look for contours on boundary first. */
  1450. static struct gnuplot_contours *contour_list = NULL;
  1451. static double crnt_cntr[MAX_POINTS_PER_CNTR * 2];
  1452. static int crnt_cntr_pt_index = 0;
  1453. static double contour_level = 0.0;
  1454. static table_entry *hermit_table = NULL;    /* Hold hermite table constants. */
  1455. static int num_of_z_levels = DEFAULT_NUM_OF_ZLEVELS;  /* # Z contour levels. */
  1456. static int num_approx_pts = DEFAULT_NUM_APPROX_PTS;/* # pts per approx/inter.*/
  1457. static int bspline_order = DEFAULT_BSPLINE_ORDER;   /* Bspline order to use. */
  1458. static int interp_kind = INTERP_NOTHING;  /* Linear, Cubic interp., Bspline. */
  1459. X
  1460. static void gen_contours();
  1461. static int update_all_edges();
  1462. static struct cntr_struct *gen_one_contour();
  1463. static struct cntr_struct *trace_contour();
  1464. static struct cntr_struct *update_cntr_pt();
  1465. static int fuzzy_equal();
  1466. static void gen_triangle();
  1467. static struct vrtx_struct *gen_vertices();
  1468. static struct edge_struct *gen_edges_middle();
  1469. static struct edge_struct *gen_edges();
  1470. static struct poly_struct *gen_polys();
  1471. static void free_contour();
  1472. static void put_contour();
  1473. static put_contour_nothing();
  1474. static put_contour_cubic();
  1475. static put_contour_bspline();
  1476. static calc_tangent();
  1477. static int count_contour();
  1478. static complete_spline_interp();
  1479. static calc_hermit_table();
  1480. static hermit_interp();
  1481. static prepare_spline_interp();
  1482. static int solve_tri_diag();
  1483. static gen_bspline_approx();
  1484. static double fetch_knot();
  1485. static eval_bspline();
  1486. X
  1487. /*
  1488. X * Entry routine to this whole set of contouring module.
  1489. X */
  1490. struct gnuplot_contours *contour(num_isolines, iso_lines,
  1491. X                 ZLevels, approx_pts, kind, order1)
  1492. int num_isolines;
  1493. struct iso_curve *iso_lines;
  1494. int ZLevels, approx_pts, kind, order1;
  1495. {
  1496. X    int i;
  1497. X    struct poly_struct *p_polys, *p_poly;
  1498. X    struct edge_struct *p_edges, *p_edge;
  1499. X    struct vrtx_struct *p_vrts, *p_vrtx;
  1500. X    double x_min, y_min, z_min, x_max, y_max, z_max, z, dz, z_scale = 1.0;
  1501. X
  1502. X    num_of_z_levels = ZLevels;
  1503. X    num_approx_pts = approx_pts;
  1504. X    bspline_order = order1 - 1;
  1505. X    interp_kind = kind;
  1506. X
  1507. X    contour_list = NULL;
  1508. X
  1509. X    if (interp_kind == INTERP_CUBIC) calc_hermit_table();
  1510. X
  1511. X    gen_triangle(num_isolines, iso_lines, &p_polys, &p_edges, &p_vrts,
  1512. X        &x_min, &y_min, &z_min, &x_max, &y_max, &z_max);
  1513. X    dz = (z_max - z_min) / (num_of_z_levels+1);
  1514. X    /* Step from z_min+dz upto z_max-dz in num_of_z_levels times. */
  1515. X    z = z_min + dz;
  1516. X    crnt_cntr_pt_index = 0;
  1517. X
  1518. X    for (i=0; i<num_of_z_levels; i++, z += dz) {
  1519. X    contour_level = z;
  1520. X    gen_contours(p_edges, z + dz * SHIFT_Z_EPSILON, x_min, x_max,
  1521. X                            y_min, y_max);
  1522. X    }
  1523. X
  1524. X    /* Free all contouring related temporary data. */
  1525. X    while (p_polys) {
  1526. X    p_poly = p_polys -> next;
  1527. X    free (p_polys);
  1528. X    p_polys = p_poly;
  1529. X    }
  1530. X    while (p_edges) {
  1531. X    p_edge = p_edges -> next;
  1532. X    free (p_edges);
  1533. X    p_edges = p_edge;
  1534. X    }
  1535. X    while (p_vrts) {
  1536. X    p_vrtx = p_vrts -> next;
  1537. X    free (p_vrts);
  1538. X    p_vrts = p_vrtx;
  1539. X    }
  1540. X
  1541. X    if (interp_kind == INTERP_CUBIC) free(hermit_table);
  1542. X
  1543. X    return contour_list;
  1544. }
  1545. X
  1546. /*
  1547. X * Adds another point to the currently build contour.
  1548. X */
  1549. add_cntr_point(x, y)
  1550. double x, y;
  1551. {
  1552. X    int index;
  1553. X
  1554. X    if (crnt_cntr_pt_index >= MAX_POINTS_PER_CNTR-1) {
  1555. X    index = crnt_cntr_pt_index - 1;
  1556. X    end_crnt_cntr();
  1557. X    crnt_cntr[0] = crnt_cntr[index * 2];
  1558. X    crnt_cntr[1] = crnt_cntr[index * 2 + 1];
  1559. X    crnt_cntr_pt_index = 1; /* Keep the last point as first of this one. */
  1560. X    }
  1561. X    crnt_cntr[crnt_cntr_pt_index * 2] = x;
  1562. X    crnt_cntr[crnt_cntr_pt_index * 2 + 1] = y;
  1563. X    crnt_cntr_pt_index++;
  1564. }
  1565. X
  1566. /*
  1567. X * Done with current contour - create gnuplot data structure for it.
  1568. X */
  1569. end_crnt_cntr()
  1570. {
  1571. X    int i;
  1572. X    struct gnuplot_contours *cntr = (struct gnuplot_contours *)
  1573. X                    alloc(sizeof(struct gnuplot_contours),
  1574. X                          "gnuplot_contour");
  1575. X
  1576. X    cntr->coords = (struct coordinate *) alloc(sizeof(struct coordinate) *
  1577. X                              crnt_cntr_pt_index,
  1578. X                           "contour coords");
  1579. X    for (i=0; i<crnt_cntr_pt_index; i++) {
  1580. X    cntr->coords[i].x = crnt_cntr[i * 2];
  1581. X    cntr->coords[i].y = crnt_cntr[i * 2 + 1];
  1582. X    cntr->coords[i].z = contour_level;
  1583. X    }
  1584. X    cntr->num_pts = crnt_cntr_pt_index;
  1585. X
  1586. X    cntr->next = contour_list;
  1587. X    contour_list = cntr;
  1588. X
  1589. X    crnt_cntr_pt_index = 0;
  1590. }
  1591. X
  1592. /*
  1593. X * Generates all contours by tracing the intersecting triangles.
  1594. X */
  1595. static void gen_contours(p_edges, z_level, x_min, x_max, y_min, y_max)
  1596. struct edge_struct *p_edges;
  1597. double z_level, x_min, x_max, y_min, y_max;
  1598. {
  1599. X    int num_active,                        /* Number of edges marked ACTIVE. */
  1600. X    contour_kind;                /* One of OPEN_CONTOUR, CLOSED_CONTOUR. */
  1601. X    struct cntr_struct *p_cntr;
  1602. X
  1603. X    num_active = update_all_edges(p_edges, z_level);           /* Do pass 1. */
  1604. X
  1605. X    test_boundary = TRUE;        /* Start to look for contour on boundaries. */
  1606. X
  1607. X    while (num_active > 0) {                                   /* Do Pass 2. */
  1608. X        /* Generate One contour (and update MumActive as needed): */
  1609. X    p_cntr = gen_one_contour(p_edges, z_level, &contour_kind, &num_active);
  1610. X    put_contour(p_cntr, z_level, x_min, x_max, y_min, y_max,
  1611. X                  contour_kind); /* Emit it in requested format. */
  1612. X    }
  1613. }
  1614. X
  1615. /*
  1616. X * Does pass 1, or marks the edges which are active (crosses this z_level)
  1617. X * as ACTIVE, and the others as INACTIVE:
  1618. X * Returns number of active edges (marked ACTIVE).
  1619. X */
  1620. static int update_all_edges(p_edges, z_level)
  1621. struct edge_struct *p_edges;
  1622. double z_level;
  1623. {
  1624. X    int count = 0;
  1625. X
  1626. X    while (p_edges) {
  1627. X    if (((p_edges -> vertex[0] -> Z >= z_level) &&
  1628. X         (p_edges -> vertex[1] -> Z <= z_level)) ||
  1629. X        ((p_edges -> vertex[1] -> Z >= z_level) &&
  1630. X         (p_edges -> vertex[0] -> Z <= z_level))) {
  1631. X        p_edges -> status = ACTIVE;
  1632. X        count++;
  1633. X    }
  1634. X    else p_edges -> status = INACTIVE;
  1635. X    p_edges = p_edges -> next;
  1636. X    }
  1637. X
  1638. X    return count;
  1639. }
  1640. X
  1641. /*
  1642. X * Does pass 2, or find one complete contour out of the triangolation data base:
  1643. X * Returns a pointer to the contour (as linked list), contour_kind is set to
  1644. X * one of OPEN_CONTOUR, CLOSED_CONTOUR, and num_active is updated.
  1645. X */
  1646. static struct cntr_struct *gen_one_contour(p_edges, z_level, contour_kind,
  1647. X                                num_active)
  1648. struct edge_struct *p_edges;
  1649. double z_level;
  1650. int *contour_kind, *num_active;
  1651. {
  1652. X    struct edge_struct *pe_temp;
  1653. X
  1654. X    if (test_boundary) {    /* Look for something to start with on boundary: */
  1655. X    pe_temp = p_edges;
  1656. X    while (pe_temp) {
  1657. X        if ((pe_temp -> status == ACTIVE) && (pe_temp -> boundary)) break;
  1658. X        pe_temp = pe_temp -> next;
  1659. X    }
  1660. X    if (!pe_temp) test_boundary = FALSE;/* No more contours on boundary. */
  1661. X    else {
  1662. X        *contour_kind = OPEN_CONTOUR;
  1663. X        return trace_contour(pe_temp, z_level, num_active, *contour_kind);
  1664. X    }
  1665. X    }
  1666. X
  1667. X    if (!test_boundary) {        /* Look for something to start with inside: */
  1668. X    pe_temp = p_edges;
  1669. X    while (pe_temp) {
  1670. X        if ((pe_temp -> status == ACTIVE) && (!(pe_temp -> boundary)))
  1671. X        break;
  1672. X        pe_temp = pe_temp -> next;
  1673. X    }
  1674. X    if (!pe_temp) {
  1675. X        *num_active = 0;
  1676. X        return NULL;
  1677. X    }
  1678. X    else {
  1679. X        *contour_kind = CLOSED_CONTOUR;
  1680. X        return trace_contour(pe_temp, z_level, num_active, *contour_kind);
  1681. X    }
  1682. X    }
  1683. X    return NULL;             /* We should never be here, but lint... */
  1684. }
  1685. X
  1686. /*
  1687. X * Search the data base along a contour starts at the edge pe_start until
  1688. X * a boundary edge is detected or until we close the loop back to pe_start.
  1689. X * Returns a linked list of all the points on the contour
  1690. X * Also decreases num_active by the number of points on contour.
  1691. X */
  1692. static struct cntr_struct *trace_contour(pe_start, z_level, num_active,
  1693. X                                contour_kind)
  1694. struct edge_struct *pe_start;
  1695. double z_level;
  1696. int *num_active, contour_kind;
  1697. {
  1698. X    int i, in_middle;       /* If TRUE the z_level is in the middle of edge. */
  1699. X    struct cntr_struct *p_cntr, *pc_tail;
  1700. X    struct edge_struct *p_edge = pe_start, *p_next_edge;
  1701. X    struct poly_struct *p_poly, *PLastpoly = NULL;
  1702. X
  1703. X    /* Generate the header of the contour - the point on pe_start. */
  1704. X    if (contour_kind == OPEN_CONTOUR) pe_start -> status = INACTIVE;
  1705. X    (*num_active)--;
  1706. X    p_cntr = pc_tail = update_cntr_pt(pe_start, z_level, &in_middle);
  1707. X    if (!in_middle) {
  1708. X    return NULL;
  1709. X    }
  1710. X
  1711. X    do {
  1712. X    /* Find polygon to continue (Not where we came from - PLastpoly): */
  1713. X    if (p_edge -> poly[0] == PLastpoly) p_poly = p_edge -> poly[1];
  1714. X    else p_poly = p_edge -> poly[0];
  1715. X    p_next_edge = NULL;          /* In case of error, remains NULL. */
  1716. X    for (i=0; i<3; i++)              /* Test the 3 edges of the polygon: */
  1717. X        if (p_poly -> edge[i] != p_edge)
  1718. X            if (p_poly -> edge[i] -> status == ACTIVE)
  1719. X            p_next_edge = p_poly -> edge[i];
  1720. X    if (!p_next_edge) {
  1721. X        pc_tail -> next = NULL;
  1722. X        free_contour(p_cntr);
  1723. X        return NULL;
  1724. X    }
  1725. X    p_edge = p_next_edge;
  1726. X    PLastpoly = p_poly;
  1727. X    p_edge -> status = INACTIVE;
  1728. X    (*num_active)--;
  1729. X    pc_tail -> next = update_cntr_pt(p_edge, z_level, &in_middle);
  1730. X    if (!in_middle) {
  1731. X        pc_tail -> next = NULL;
  1732. X        free_contour(p_cntr);
  1733. X        return NULL;
  1734. X    }
  1735. X        pc_tail = pc_tail -> next;
  1736. X    }
  1737. X    while ((pe_start != p_edge) && (!p_edge -> boundary));
  1738. X    pc_tail -> next = NULL;
  1739. X
  1740. X    return p_cntr;
  1741. }
  1742. X
  1743. /*
  1744. X * Allocates one contour location and update it to to correct position
  1745. X * according to z_level and edge p_edge. if z_level is found to be at
  1746. X * one of the extreme points nothing is allocated (NULL is returned)
  1747. X * and in_middle is set to FALSE.
  1748. X */
  1749. static struct cntr_struct *update_cntr_pt(p_edge, z_level, in_middle)
  1750. struct edge_struct *p_edge;
  1751. double z_level;
  1752. int *in_middle;
  1753. {
  1754. X    double t;
  1755. X    struct cntr_struct *p_cntr;
  1756. X
  1757. X    t = (z_level - p_edge -> vertex[0] -> Z) /
  1758. X    (p_edge -> vertex[1] -> Z - p_edge -> vertex[0] -> Z);
  1759. X
  1760. X    if (fuzzy_equal(t, 1.0) || fuzzy_equal(t, 0.0)) {
  1761. X        *in_middle = FALSE;
  1762. X        return NULL;
  1763. X    }
  1764. X    else {
  1765. X    *in_middle = TRUE;
  1766. X    p_cntr = (struct cntr_struct *) alloc(sizeof(struct cntr_struct),
  1767. SHAR_EOF
  1768. true || echo 'restore of gnuplot/contour.c failed'
  1769. fi
  1770. echo 'End of  part 4'
  1771. echo 'File gnuplot/contour.c is continued in part 5'
  1772. echo 5 > _shar_seq_.tmp
  1773. exit 0
  1774.  
  1775. exit 0 # Just in case...
  1776. -- 
  1777. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1778. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1779. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1780. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1781.