home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume40 / gnuplot / part17 < prev    next >
Encoding:
Text File  |  1993-10-22  |  79.3 KB  |  2,935 lines

  1. Newsgroups: comp.sources.misc
  2. From: woo@playfair.stanford.edu ("Alexander Woo")
  3. Subject: v40i029:  gnuplot - interactive function plotting utility, Part17/33
  4. Message-ID: <1993Oct22.163549.24123@sparky.sterling.com>
  5. X-Md4-Signature: d6eb3fd2db67e4a1323d9b026434d4a4
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 22 Oct 1993 16:35:49 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: woo@playfair.stanford.edu ("Alexander Woo")
  12. Posting-number: Volume 40, Issue 29
  13. Archive-name: gnuplot/part17
  14. Environment: UNIX, MS-DOS, VMS
  15. Supersedes: gnuplot3: Volume 24, Issue 23-48
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  gnuplot/docs/doc2hlp.com gnuplot/internal.c
  22. #   gnuplot/os2/gclient.c gnuplot/specfun.c
  23. # Wrapped by kent@sparky on Wed Oct 20 17:14:51 1993
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 17 (of 33)."'
  27. if test -f 'gnuplot/docs/doc2hlp.com' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'gnuplot/docs/doc2hlp.com'\"
  29. else
  30.   echo shar: Extracting \"'gnuplot/docs/doc2hlp.com'\" \(90 characters\)
  31.   sed "s/^X//" >'gnuplot/docs/doc2hlp.com' <<'END_OF_FILE'
  32. X$ def/user sys$input [.docs]gnuplot.doc
  33. X$ def/user sys$output []gnuplot.hlp
  34. X$ run doc2hlp
  35. END_OF_FILE
  36.   if test 90 -ne `wc -c <'gnuplot/docs/doc2hlp.com'`; then
  37.     echo shar: \"'gnuplot/docs/doc2hlp.com'\" unpacked with wrong size!
  38.   fi
  39.   # end of 'gnuplot/docs/doc2hlp.com'
  40. fi
  41. if test -f 'gnuplot/internal.c' -a "${1}" != "-c" ; then 
  42.   echo shar: Will not clobber existing file \"'gnuplot/internal.c'\"
  43. else
  44.   echo shar: Extracting \"'gnuplot/internal.c'\" \(16884 characters\)
  45.   sed "s/^X//" >'gnuplot/internal.c' <<'END_OF_FILE'
  46. X#ifndef lint
  47. Xstatic char *RCSid = "$Id: internal.c%v 3.50.1.8 1993/07/27 05:37:15 woo Exp $";
  48. X#endif
  49. X
  50. X
  51. X/* GNUPLOT - internal.c */
  52. X/*
  53. X * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  54. X *
  55. X * Permission to use, copy, and distribute this software and its
  56. X * documentation for any purpose with or without fee is hereby granted, 
  57. X * provided that the above copyright notice appear in all copies and 
  58. X * that both that copyright notice and this permission notice appear 
  59. X * in supporting documentation.
  60. X *
  61. X * Permission to modify the software is granted, but not the right to
  62. X * distribute the modified code.  Modifications are to be distributed 
  63. X * as patches to released version.
  64. X *  
  65. X * This software is provided "as is" without express or implied warranty.
  66. X * 
  67. X *
  68. X * AUTHORS
  69. X * 
  70. X *   Original Software:
  71. X *     Thomas Williams,  Colin Kelley.
  72. X * 
  73. X *   Gnuplot 2.0 additions:
  74. X *       Russell Lang, Dave Kotz, John Campbell.
  75. X *
  76. X *   Gnuplot 3.0 additions:
  77. X *       Gershon Elber and many others.
  78. X * 
  79. X */
  80. X
  81. X#include <math.h>
  82. X#include <stdio.h>
  83. X#include "plot.h"
  84. X
  85. XTBOOLEAN undefined;
  86. X
  87. X#ifndef AMIGA_SC_6_1
  88. Xchar *strcpy();
  89. X#endif /* !AMIGA_SC_6_1 */
  90. X
  91. Xstruct value *pop(), *Gcomplex(), *Ginteger();
  92. Xdouble magnitude(), angle(), real();
  93. X
  94. Xstruct value stack[STACK_DEPTH];
  95. X
  96. Xint s_p = -1;   /* stack pointer */
  97. X
  98. X
  99. X/*
  100. X * System V and MSC 4.0 call this when they wants to print an error message.
  101. X * Don't!
  102. X */
  103. X#ifndef _CRAY
  104. X#if defined(MSDOS) || defined(DOS386)
  105. X#ifdef __TURBOC__
  106. Xint matherr()    /* Turbo C */
  107. X#else
  108. Xint matherr(x)    /* MSC 5.1 */
  109. Xstruct exception *x;
  110. X#endif /* TURBOC */
  111. X#else /* not MSDOS */
  112. X#ifdef apollo
  113. Xint matherr(struct exception *x)    /* apollo */
  114. X#else /* apollo */
  115. X#if defined(AMIGA_SC_6_1)||defined(ATARI)&&defined(__GNUC__)||defined(__hpux__)||defined(PLOSS) ||defined(SOLARIS)
  116. Xint matherr(x)
  117. Xstruct exception *x;
  118. X#else    /* Most everyone else (not apollo). */
  119. Xint matherr()
  120. X#endif /* AMIGA_SC_6_1 || GCC_ST */
  121. X#endif /* apollo */
  122. X#endif /* MSDOS */
  123. X{
  124. X    return (undefined = TRUE);        /* don't print error message */
  125. X}
  126. X#endif /* not _CRAY */
  127. X
  128. X
  129. Xreset_stack()
  130. X{
  131. X    s_p = -1;
  132. X}
  133. X
  134. X
  135. Xcheck_stack()    /* make sure stack's empty */
  136. X{
  137. X    if (s_p != -1)
  138. X        fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
  139. X}
  140. X
  141. X
  142. Xstruct value *pop(x)
  143. Xstruct value *x;
  144. X{
  145. X    if (s_p  < 0 )
  146. X        int_error("stack underflow",NO_CARET);
  147. X    *x = stack[s_p--];
  148. X    return(x);
  149. X}
  150. X
  151. X
  152. Xpush(x)
  153. Xstruct value *x;
  154. X{
  155. X    if (s_p == STACK_DEPTH - 1)
  156. X        int_error("stack overflow",NO_CARET);
  157. X    stack[++s_p] = *x;
  158. X}
  159. X
  160. X
  161. X#define ERR_VAR "undefined variable: "
  162. X
  163. Xf_push(x)
  164. Xunion argument *x;        /* contains pointer to value to push; */
  165. X{
  166. Xstatic char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
  167. Xstruct udvt_entry *udv;
  168. X
  169. X    udv = x->udv_arg;
  170. X    if (udv->udv_undef) {     /* undefined */
  171. X        (void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
  172. X        int_error(err_str,NO_CARET);
  173. X    }
  174. X    push(&(udv->udv_value));
  175. X}
  176. X
  177. X
  178. Xf_pushc(x)
  179. Xunion argument *x;
  180. X{
  181. X    push(&(x->v_arg));
  182. X}
  183. X
  184. X
  185. Xf_pushd1(x)
  186. Xunion argument *x;
  187. X{
  188. X    push(&(x->udf_arg->dummy_values[0]));
  189. X}
  190. X
  191. X
  192. Xf_pushd2(x)
  193. Xunion argument *x;
  194. X{
  195. X    push(&(x->udf_arg->dummy_values[1]));
  196. X}
  197. X
  198. X
  199. Xf_pushd(x)
  200. Xunion argument *x;
  201. X{
  202. Xstruct value param;
  203. X    (void) pop(¶m);
  204. X    push(&(x->udf_arg->dummy_values[param.v.int_val]));
  205. X}
  206. X
  207. X
  208. X#define ERR_FUN "undefined function: "
  209. X
  210. Xf_call(x)  /* execute a udf */
  211. Xunion argument *x;
  212. X{
  213. Xstatic char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  214. Xregister struct udft_entry *udf;
  215. Xstruct value save_dummy;
  216. X
  217. X    udf = x->udf_arg;
  218. X    if (!udf->at) { /* undefined */
  219. X        (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  220. X                udf->udf_name);
  221. X        int_error(err_str,NO_CARET);
  222. X    }
  223. X    save_dummy = udf->dummy_values[0];
  224. X    (void) pop(&(udf->dummy_values[0]));
  225. X
  226. X    execute_at(udf->at);
  227. X    udf->dummy_values[0] = save_dummy;
  228. X}
  229. X
  230. X
  231. Xf_calln(x)  /* execute a udf of n variables */
  232. Xunion argument *x;
  233. X{
  234. Xstatic char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  235. Xregister struct udft_entry *udf;
  236. Xstruct value save_dummy[MAX_NUM_VAR];
  237. X
  238. X    int i;
  239. X    int num_pop;
  240. X    struct value num_params;
  241. X
  242. X    udf = x->udf_arg;
  243. X    if (!udf->at) { /* undefined */
  244. X        (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  245. X                udf->udf_name);
  246. X        int_error(err_str,NO_CARET);
  247. X    }
  248. X    for(i=0; i<MAX_NUM_VAR; i++) 
  249. X        save_dummy[i] = udf->dummy_values[i];
  250. X
  251. X    /* if there are more parameters than the function is expecting */
  252. X    /* simply ignore the excess */
  253. X    (void) pop(&num_params);
  254. X
  255. X    if(num_params.v.int_val > MAX_NUM_VAR) {
  256. X        /* pop the dummies that there is no room for */
  257. X        num_pop = num_params.v.int_val - MAX_NUM_VAR;
  258. X        for(i=0; i< num_pop; i++)
  259. X            (void) pop(&(udf->dummy_values[i]));
  260. X
  261. X        num_pop = MAX_NUM_VAR;
  262. X    } else {
  263. X        num_pop = num_params.v.int_val;
  264. X    }
  265. X
  266. X    /* pop parameters we can use */
  267. X    for(i=num_pop-1; i>=0; i--)
  268. X        (void) pop(&(udf->dummy_values[i]));
  269. X
  270. X    execute_at(udf->at);
  271. X    for(i=0; i<MAX_NUM_VAR; i++) 
  272. X        udf->dummy_values[i] = save_dummy[i];
  273. X}
  274. X
  275. X
  276. Xstatic int_check(v)
  277. Xstruct value *v;
  278. X{
  279. X    if (v->type != INTGR)
  280. X        int_error("non-integer passed to boolean operator",NO_CARET);
  281. X}
  282. X
  283. X
  284. Xf_lnot()
  285. X{
  286. Xstruct value a;
  287. X    int_check(pop(&a));
  288. X    push(Ginteger(&a,!a.v.int_val) );
  289. X}
  290. X
  291. X
  292. Xf_bnot()
  293. X{
  294. Xstruct value a;
  295. X    int_check(pop(&a));
  296. X    push( Ginteger(&a,~a.v.int_val) );
  297. X}
  298. X
  299. X
  300. Xf_bool()
  301. X{            /* converts top-of-stack to boolean */
  302. X    int_check(&top_of_stack);
  303. X    top_of_stack.v.int_val = !!top_of_stack.v.int_val;
  304. X}
  305. X
  306. X
  307. Xf_lor()
  308. X{
  309. Xstruct value a,b;
  310. X    int_check(pop(&b));
  311. X    int_check(pop(&a));
  312. X    push( Ginteger(&a,a.v.int_val || b.v.int_val) );
  313. X}
  314. X
  315. Xf_land()
  316. X{
  317. Xstruct value a,b;
  318. X    int_check(pop(&b));
  319. X    int_check(pop(&a));
  320. X    push( Ginteger(&a,a.v.int_val && b.v.int_val) );
  321. X}
  322. X
  323. X
  324. Xf_bor()
  325. X{
  326. Xstruct value a,b;
  327. X    int_check(pop(&b));
  328. X    int_check(pop(&a));
  329. X    push( Ginteger(&a,a.v.int_val | b.v.int_val) );
  330. X}
  331. X
  332. X
  333. Xf_xor()
  334. X{
  335. Xstruct value a,b;
  336. X    int_check(pop(&b));
  337. X    int_check(pop(&a));
  338. X    push( Ginteger(&a,a.v.int_val ^ b.v.int_val) );
  339. X}
  340. X
  341. X
  342. Xf_band()
  343. X{
  344. Xstruct value a,b;
  345. X    int_check(pop(&b));
  346. X    int_check(pop(&a));
  347. X    push( Ginteger(&a,a.v.int_val & b.v.int_val) );
  348. X}
  349. X
  350. X
  351. Xf_uminus()
  352. X{
  353. Xstruct value a;
  354. X    (void) pop(&a);
  355. X    switch(a.type) {
  356. X        case INTGR:
  357. X            a.v.int_val = -a.v.int_val;
  358. X            break;
  359. X        case CMPLX:
  360. X            a.v.cmplx_val.real =
  361. X                -a.v.cmplx_val.real;
  362. X            a.v.cmplx_val.imag =
  363. X                -a.v.cmplx_val.imag;
  364. X    }
  365. X    push(&a);
  366. X}
  367. X
  368. X
  369. Xf_eq() /* note: floating point equality is rare because of roundoff error! */
  370. X{
  371. Xstruct value a, b;
  372. X    register int result;
  373. X    (void) pop(&b);
  374. X    (void) pop(&a);
  375. X    switch(a.type) {
  376. X        case INTGR:
  377. X            switch (b.type) {
  378. X                case INTGR:
  379. X                    result = (a.v.int_val ==
  380. X                        b.v.int_val);
  381. X                    break;
  382. X                case CMPLX:
  383. X                    result = (a.v.int_val ==
  384. X                        b.v.cmplx_val.real &&
  385. X                       b.v.cmplx_val.imag == 0.0);
  386. X            }
  387. X            break;
  388. X        case CMPLX:
  389. X            switch (b.type) {
  390. X                case INTGR:
  391. X                    result = (b.v.int_val == a.v.cmplx_val.real &&
  392. X                       a.v.cmplx_val.imag == 0.0);
  393. X                    break;
  394. X                case CMPLX:
  395. X                    result = (a.v.cmplx_val.real==
  396. X                        b.v.cmplx_val.real &&
  397. X                        a.v.cmplx_val.imag==
  398. X                        b.v.cmplx_val.imag);
  399. X            }
  400. X    }
  401. X    push(Ginteger(&a,result));
  402. X}
  403. X
  404. X
  405. Xf_ne()
  406. X{
  407. Xstruct value a, b;
  408. X    register int result;
  409. X    (void) pop(&b);
  410. X    (void) pop(&a);
  411. X    switch(a.type) {
  412. X        case INTGR:
  413. X            switch (b.type) {
  414. X                case INTGR:
  415. X                    result = (a.v.int_val !=
  416. X                        b.v.int_val);
  417. X                    break;
  418. X                case CMPLX:
  419. X                    result = (a.v.int_val !=
  420. X                        b.v.cmplx_val.real ||
  421. X                       b.v.cmplx_val.imag != 0.0);
  422. X            }
  423. X            break;
  424. X        case CMPLX:
  425. X            switch (b.type) {
  426. X                case INTGR:
  427. X                    result = (b.v.int_val !=
  428. X                        a.v.cmplx_val.real ||
  429. X                       a.v.cmplx_val.imag != 0.0);
  430. X                    break;
  431. X                case CMPLX:
  432. X                    result = (a.v.cmplx_val.real !=
  433. X                        b.v.cmplx_val.real ||
  434. X                        a.v.cmplx_val.imag !=
  435. X                        b.v.cmplx_val.imag);
  436. X            }
  437. X    }
  438. X    push(Ginteger(&a,result));
  439. X}
  440. X
  441. X
  442. Xf_gt()
  443. X{
  444. Xstruct value a, b;
  445. X    register int result;
  446. X    (void) pop(&b);
  447. X    (void) pop(&a);
  448. X    switch(a.type) {
  449. X        case INTGR:
  450. X            switch (b.type) {
  451. X                case INTGR:
  452. X                    result = (a.v.int_val >
  453. X                        b.v.int_val);
  454. X                    break;
  455. X                case CMPLX:
  456. X                    result = (a.v.int_val >
  457. X                        b.v.cmplx_val.real);
  458. X            }
  459. X            break;
  460. X        case CMPLX:
  461. X            switch (b.type) {
  462. X                case INTGR:
  463. X                    result = (a.v.cmplx_val.real >
  464. X                        b.v.int_val);
  465. X                    break;
  466. X                case CMPLX:
  467. X                    result = (a.v.cmplx_val.real >
  468. X                        b.v.cmplx_val.real);
  469. X            }
  470. X    }
  471. X    push(Ginteger(&a,result));
  472. X}
  473. X
  474. X
  475. Xf_lt()
  476. X{
  477. Xstruct value a, b;
  478. X    register int result;
  479. X    (void) pop(&b);
  480. X    (void) pop(&a);
  481. X    switch(a.type) {
  482. X        case INTGR:
  483. X            switch (b.type) {
  484. X                case INTGR:
  485. X                    result = (a.v.int_val <
  486. X                        b.v.int_val);
  487. X                    break;
  488. X                case CMPLX:
  489. X                    result = (a.v.int_val <
  490. X                        b.v.cmplx_val.real);
  491. X            }
  492. X            break;
  493. X        case CMPLX:
  494. X            switch (b.type) {
  495. X                case INTGR:
  496. X                    result = (a.v.cmplx_val.real <
  497. X                        b.v.int_val);
  498. X                    break;
  499. X                case CMPLX:
  500. X                    result = (a.v.cmplx_val.real <
  501. X                        b.v.cmplx_val.real);
  502. X            }
  503. X    }
  504. X    push(Ginteger(&a,result));
  505. X}
  506. X
  507. X
  508. Xf_ge()
  509. X{
  510. Xstruct value a, b;
  511. X    register int result;
  512. X    (void) pop(&b);
  513. X    (void) pop(&a);
  514. X    switch(a.type) {
  515. X        case INTGR:
  516. X            switch (b.type) {
  517. X                case INTGR:
  518. X                    result = (a.v.int_val >=
  519. X                        b.v.int_val);
  520. X                    break;
  521. X                case CMPLX:
  522. X                    result = (a.v.int_val >=
  523. X                        b.v.cmplx_val.real);
  524. X            }
  525. X            break;
  526. X        case CMPLX:
  527. X            switch (b.type) {
  528. X                case INTGR:
  529. X                    result = (a.v.cmplx_val.real >=
  530. X                        b.v.int_val);
  531. X                    break;
  532. X                case CMPLX:
  533. X                    result = (a.v.cmplx_val.real >=
  534. X                        b.v.cmplx_val.real);
  535. X            }
  536. X    }
  537. X    push(Ginteger(&a,result));
  538. X}
  539. X
  540. X
  541. Xf_le()
  542. X{
  543. Xstruct value a, b;
  544. X    register int result;
  545. X    (void) pop(&b);
  546. X    (void) pop(&a);
  547. X    switch(a.type) {
  548. X        case INTGR:
  549. X            switch (b.type) {
  550. X                case INTGR:
  551. X                    result = (a.v.int_val <=
  552. X                        b.v.int_val);
  553. X                    break;
  554. X                case CMPLX:
  555. X                    result = (a.v.int_val <=
  556. X                        b.v.cmplx_val.real);
  557. X            }
  558. X            break;
  559. X        case CMPLX:
  560. X            switch (b.type) {
  561. X                case INTGR:
  562. X                    result = (a.v.cmplx_val.real <=
  563. X                        b.v.int_val);
  564. X                    break;
  565. X                case CMPLX:
  566. X                    result = (a.v.cmplx_val.real <=
  567. X                        b.v.cmplx_val.real);
  568. X            }
  569. X    }
  570. X    push(Ginteger(&a,result));
  571. X}
  572. X
  573. X
  574. Xf_plus()
  575. X{
  576. Xstruct value a, b, result;
  577. X    (void) pop(&b);
  578. X    (void) pop(&a);
  579. X    switch(a.type) {
  580. X        case INTGR:
  581. X            switch (b.type) {
  582. X                case INTGR:
  583. X                    (void) Ginteger(&result,a.v.int_val +
  584. X                        b.v.int_val);
  585. X                    break;
  586. X                case CMPLX:
  587. X                    (void) Gcomplex(&result,a.v.int_val +
  588. X                        b.v.cmplx_val.real,
  589. X                       b.v.cmplx_val.imag);
  590. X            }
  591. X            break;
  592. X        case CMPLX:
  593. X            switch (b.type) {
  594. X                case INTGR:
  595. X                    (void) Gcomplex(&result,b.v.int_val +
  596. X                        a.v.cmplx_val.real,
  597. X                       a.v.cmplx_val.imag);
  598. X                    break;
  599. X                case CMPLX:
  600. X                    (void) Gcomplex(&result,a.v.cmplx_val.real+
  601. X                        b.v.cmplx_val.real,
  602. X                        a.v.cmplx_val.imag+
  603. X                        b.v.cmplx_val.imag);
  604. X            }
  605. X    }
  606. X    push(&result);
  607. X}
  608. X
  609. X
  610. Xf_minus()
  611. X{
  612. Xstruct value a, b, result;
  613. X    (void) pop(&b);
  614. X    (void) pop(&a);        /* now do a - b */
  615. X    switch(a.type) {
  616. X        case INTGR:
  617. X            switch (b.type) {
  618. X                case INTGR:
  619. X                    (void) Ginteger(&result,a.v.int_val -
  620. X                        b.v.int_val);
  621. X                    break;
  622. X                case CMPLX:
  623. X                    (void) Gcomplex(&result,a.v.int_val -
  624. X                        b.v.cmplx_val.real,
  625. X                       -b.v.cmplx_val.imag);
  626. X            }
  627. X            break;
  628. X        case CMPLX:
  629. X            switch (b.type) {
  630. X                case INTGR:
  631. X                    (void) Gcomplex(&result,a.v.cmplx_val.real -
  632. X                        b.v.int_val,
  633. X                        a.v.cmplx_val.imag);
  634. X                    break;
  635. X                case CMPLX:
  636. X                    (void) Gcomplex(&result,a.v.cmplx_val.real-
  637. X                        b.v.cmplx_val.real,
  638. X                        a.v.cmplx_val.imag-
  639. X                        b.v.cmplx_val.imag);
  640. X            }
  641. X    }
  642. X    push(&result);
  643. X}
  644. X
  645. X
  646. Xf_mult()
  647. X{
  648. Xstruct value a, b, result;
  649. X    (void) pop(&b);
  650. X    (void) pop(&a);    /* now do a*b */
  651. X
  652. X    switch(a.type) {
  653. X        case INTGR:
  654. X            switch (b.type) {
  655. X                case INTGR:
  656. X                    (void) Ginteger(&result,a.v.int_val *
  657. X                        b.v.int_val);
  658. X                    break;
  659. X                case CMPLX:
  660. X                    (void) Gcomplex(&result,a.v.int_val *
  661. X                        b.v.cmplx_val.real,
  662. X                        a.v.int_val *
  663. X                        b.v.cmplx_val.imag);
  664. X            }
  665. X            break;
  666. X        case CMPLX:
  667. X            switch (b.type) {
  668. X                case INTGR:
  669. X                    (void) Gcomplex(&result,b.v.int_val *
  670. X                        a.v.cmplx_val.real,
  671. X                        b.v.int_val *
  672. X                        a.v.cmplx_val.imag);
  673. X                    break;
  674. X                case CMPLX:
  675. X                    (void) Gcomplex(&result,a.v.cmplx_val.real*
  676. X                        b.v.cmplx_val.real-
  677. X                        a.v.cmplx_val.imag*
  678. X                        b.v.cmplx_val.imag,
  679. X                        a.v.cmplx_val.real*
  680. X                        b.v.cmplx_val.imag+
  681. X                        a.v.cmplx_val.imag*
  682. X                        b.v.cmplx_val.real);
  683. X            }
  684. X    }
  685. X    push(&result);
  686. X}
  687. X
  688. X
  689. Xf_div()
  690. X{
  691. Xstruct value a, b, result;
  692. Xregister double square;
  693. X    (void) pop(&b);
  694. X    (void) pop(&a);    /* now do a/b */
  695. X
  696. X    switch(a.type) {
  697. X        case INTGR:
  698. X            switch (b.type) {
  699. X                case INTGR:
  700. X                    if (b.v.int_val)
  701. X                      (void) Ginteger(&result,a.v.int_val /
  702. X                        b.v.int_val);
  703. X                    else {
  704. X                      (void) Ginteger(&result,0);
  705. X                      undefined = TRUE;
  706. X                    }
  707. X                    break;
  708. X                case CMPLX:
  709. X                    square = b.v.cmplx_val.real*
  710. X                        b.v.cmplx_val.real +
  711. X                        b.v.cmplx_val.imag*
  712. X                        b.v.cmplx_val.imag;
  713. X                    if (square)
  714. X                        (void) Gcomplex(&result,a.v.int_val*
  715. X                        b.v.cmplx_val.real/square,
  716. X                        -a.v.int_val*
  717. X                        b.v.cmplx_val.imag/square);
  718. X                    else {
  719. X                        (void) Gcomplex(&result,0.0,0.0);
  720. X                        undefined = TRUE;
  721. X                    }
  722. X            }
  723. X            break;
  724. X        case CMPLX:
  725. X            switch (b.type) {
  726. X                case INTGR:
  727. X                    if (b.v.int_val)
  728. X                      
  729. X                      (void) Gcomplex(&result,a.v.cmplx_val.real/
  730. X                        b.v.int_val,
  731. X                        a.v.cmplx_val.imag/
  732. X                        b.v.int_val);
  733. X                    else {
  734. X                        (void) Gcomplex(&result,0.0,0.0);
  735. X                        undefined = TRUE;
  736. X                    }
  737. X                    break;
  738. X                case CMPLX:
  739. X                    square = b.v.cmplx_val.real*
  740. X                        b.v.cmplx_val.real +
  741. X                        b.v.cmplx_val.imag*
  742. X                        b.v.cmplx_val.imag;
  743. X                    if (square)
  744. X                    (void) Gcomplex(&result,(a.v.cmplx_val.real*
  745. X                        b.v.cmplx_val.real+
  746. X                        a.v.cmplx_val.imag*
  747. X                        b.v.cmplx_val.imag)/square,
  748. X                        (a.v.cmplx_val.imag*
  749. X                        b.v.cmplx_val.real-
  750. X                        a.v.cmplx_val.real*
  751. X                        b.v.cmplx_val.imag)/
  752. X                            square);
  753. X                    else {
  754. X                        (void) Gcomplex(&result,0.0,0.0);
  755. X                        undefined = TRUE;
  756. X                    }
  757. X            }
  758. X    }
  759. X    push(&result);
  760. X}
  761. X
  762. X
  763. Xf_mod()
  764. X{
  765. Xstruct value a, b;
  766. X    (void) pop(&b);
  767. X    (void) pop(&a);    /* now do a%b */
  768. X
  769. X    if (a.type != INTGR || b.type != INTGR)
  770. X        int_error("can only mod ints",NO_CARET);
  771. X    if (b.v.int_val)
  772. X        push(Ginteger(&a,a.v.int_val % b.v.int_val));
  773. X    else {
  774. X        push(Ginteger(&a,0));
  775. X        undefined = TRUE;
  776. X    }
  777. X}
  778. X
  779. X
  780. Xf_power()
  781. X{
  782. Xstruct value a, b, result;
  783. Xregister int i, t, count;
  784. Xregister double mag, ang;
  785. X    (void) pop(&b);
  786. X    (void) pop(&a);    /* now find a**b */
  787. X
  788. X    switch(a.type) {
  789. X        case INTGR:
  790. X            switch (b.type) {
  791. X                case INTGR:
  792. X                    count = abs(b.v.int_val);
  793. X                    t = 1;
  794. X                    for(i = 0; i < count; i++)
  795. X                        t *= a.v.int_val;
  796. X                    if (b.v.int_val >= 0)
  797. X                        (void) Ginteger(&result,t);
  798. X                    else
  799. X                      if (t != 0)
  800. X                        (void) Gcomplex(&result,1.0/t,0.0);
  801. X                      else {
  802. X                         undefined = TRUE;
  803. X                         (void) Gcomplex(&result, 0.0, 0.0);
  804. X                      }
  805. X                    break;
  806. X                case CMPLX:
  807. X                    mag =
  808. X                      pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  809. X                    if (b.v.cmplx_val.real < 0.0)
  810. X                      if (mag != 0.0)
  811. X                        mag = 1.0/mag;
  812. X                      else 
  813. X                        undefined = TRUE;
  814. X                    mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  815. X                    ang = b.v.cmplx_val.real*angle(&a) +
  816. X                          b.v.cmplx_val.imag*log(magnitude(&a));
  817. X                    (void) Gcomplex(&result,mag*cos(ang),
  818. X                        mag*sin(ang));
  819. X            }
  820. X            break;
  821. X        case CMPLX:
  822. X            switch (b.type) {
  823. X                case INTGR:
  824. X                    if (a.v.cmplx_val.imag == 0.0) {
  825. X                        mag = pow(a.v.cmplx_val.real,(double)abs(b.v.int_val));
  826. X                        if (b.v.int_val < 0)
  827. X                          if (mag != 0.0)
  828. X                            mag = 1.0/mag;
  829. X                          else 
  830. X                            undefined = TRUE;
  831. X                        (void) Gcomplex(&result,mag,0.0);
  832. X                    }
  833. X                    else {
  834. X                        /* not so good, but...! */
  835. X                        mag = pow(magnitude(&a),(double)abs(b.v.int_val));
  836. X                        if (b.v.int_val < 0)
  837. X                          if (mag != 0.0)
  838. X                            mag = 1.0/mag;
  839. X                          else 
  840. X                            undefined = TRUE;
  841. X                        ang = angle(&a)*b.v.int_val;
  842. X                        (void) Gcomplex(&result,mag*cos(ang),
  843. X                            mag*sin(ang));
  844. X                    }
  845. X                    break;
  846. X                case CMPLX:
  847. X                    mag = pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  848. X                    if (b.v.cmplx_val.real < 0.0)
  849. X                      if (mag != 0.0)
  850. X                        mag = 1.0/mag;
  851. X                      else 
  852. X                        undefined = TRUE;
  853. X                    mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  854. X                    ang = b.v.cmplx_val.real*angle(&a) +
  855. X                          b.v.cmplx_val.imag*log(magnitude(&a));
  856. X                    (void) Gcomplex(&result,mag*cos(ang),
  857. X                        mag*sin(ang));
  858. X            }
  859. X    }
  860. X    push(&result);
  861. X}
  862. X
  863. X
  864. Xf_factorial()
  865. X{
  866. Xstruct value a;
  867. Xregister int i;
  868. Xregister double val;
  869. X
  870. X    (void) pop(&a);    /* find a! (factorial) */
  871. X
  872. X    switch (a.type) {
  873. X        case INTGR:
  874. X            val = 1.0;
  875. X            for (i = a.v.int_val; i > 1; i--)  /*fpe's should catch overflows*/
  876. X                val *= i;
  877. X            break;
  878. X        default:
  879. X            int_error("factorial (!) argument must be an integer",
  880. X            NO_CARET);
  881. X        }
  882. X
  883. X    push(Gcomplex(&a,val,0.0));
  884. X            
  885. X}
  886. X
  887. X
  888. Xint
  889. Xf_jump(x)
  890. Xunion argument *x;
  891. X{
  892. X    return(x->j_arg);
  893. X}
  894. X
  895. X
  896. Xint
  897. Xf_jumpz(x)
  898. Xunion argument *x;
  899. X{
  900. Xstruct value a;
  901. X    int_check(&top_of_stack);
  902. X    if (top_of_stack.v.int_val) {    /* non-zero */
  903. X        (void) pop(&a);
  904. X        return 1;                /* no jump */
  905. X    }
  906. X    else
  907. X        return(x->j_arg);        /* leave the argument on TOS */
  908. X}
  909. X
  910. X
  911. Xint
  912. Xf_jumpnz(x)
  913. Xunion argument *x;
  914. X{
  915. Xstruct value a;
  916. X    int_check(&top_of_stack);
  917. X    if (top_of_stack.v.int_val)    /* non-zero */
  918. X        return(x->j_arg);        /* leave the argument on TOS */
  919. X    else {
  920. X        (void) pop(&a);
  921. X        return 1;                /* no jump */
  922. X    }
  923. X}
  924. X
  925. X
  926. Xint
  927. Xf_jtern(x)
  928. Xunion argument *x;
  929. X{
  930. Xstruct value a;
  931. X
  932. X    int_check(pop(&a));
  933. X    if (a.v.int_val)
  934. X        return(1);                /* no jump; fall through to TRUE code */
  935. X    else
  936. X        return(x->j_arg);        /* go jump to FALSE code */
  937. X}
  938. END_OF_FILE
  939.   if test 16884 -ne `wc -c <'gnuplot/internal.c'`; then
  940.     echo shar: \"'gnuplot/internal.c'\" unpacked with wrong size!
  941.   fi
  942.   # end of 'gnuplot/internal.c'
  943. fi
  944. if test -f 'gnuplot/os2/gclient.c' -a "${1}" != "-c" ; then 
  945.   echo shar: Will not clobber existing file \"'gnuplot/os2/gclient.c'\"
  946. else
  947.   echo shar: Extracting \"'gnuplot/os2/gclient.c'\" \(37236 characters\)
  948.   sed "s/^X//" >'gnuplot/os2/gclient.c' <<'END_OF_FILE'
  949. X#ifdef INCRCSDATA
  950. Xstatic char RCSid[]="$Id: gclient.c%v 3.50 1993/07/09 05:35:24 woo Exp $" ;
  951. X#endif
  952. X
  953. X/****************************************************************************
  954. X
  955. X    PROGRAM: Gnupmdrv
  956. X    
  957. X    MODULE:  gclient.c
  958. X        
  959. X    This file contains the client window procedures for Gnupmdrv
  960. X    
  961. X****************************************************************************/
  962. X
  963. X/*
  964. X * PM driver for GNUPLOT
  965. X * Copyright (C) 1992   Roger Fearick
  966. X *
  967. X * Permission to use, copy, and distribute this software and its
  968. X * documentation for any purpose with or without fee is hereby granted, 
  969. X * provided that the above copyright notice appear in all copies and 
  970. X * that both that copyright notice and this permission notice appear 
  971. X * in supporting documentation.
  972. X *
  973. X * Permission to modify the software is granted, but not the right to
  974. X * distribute the modified code.  Modifications are to be distributed 
  975. X * as patches to released version.
  976. X *  
  977. X * This software is provided "as is" without express or implied warranty.
  978. X * 
  979. X *
  980. X * AUTHOR
  981. X * 
  982. X *   Gnuplot driver for OS/2:  Roger Fearick
  983. X * 
  984. X * Send your comments or suggestions to 
  985. X *  info-gnuplot@dartmouth.edu.
  986. X * This is a mailing list; to join it send a note to 
  987. X *  info-gnuplot-request@dartmouth.edu.  
  988. X * Send bug reports to
  989. X *  bug-gnuplot@dartmouth.edu.
  990. X**/
  991. X
  992. X#define INCL_PM
  993. X#define INCL_WIN
  994. X#define INCL_SPL
  995. X#define INCL_SPLDOSPRINT
  996. X#define INCL_WINSTDFONT
  997. X#define INCL_DOSMEMMGR
  998. X#define INCL_DOSPROCESS
  999. X#define INCL_DOSERRORS
  1000. X#define INCL_DOSFILEMGR
  1001. X#define INCL_DOSNMPIPES
  1002. X#define INCL_DOSSESMGR
  1003. X#define INCL_DOSSEMAPHORES
  1004. X#define INCL_DOSMISC
  1005. X#define INCL_DOSQUEUES
  1006. X#define INCL_WINSWITCHLIST
  1007. X#include <os2.h>
  1008. X#include <string.h>
  1009. X#include <stdio.h>
  1010. X#include <stdlib.h>
  1011. X#include <unistd.h>
  1012. X#include <process.h>
  1013. X#include "gnupmdrv.h"
  1014. X
  1015. X/*==== g l o b a l    d a t a ================================================*/
  1016. X
  1017. Xextern char szIPCName[] ;       /* name used in IPC with gnuplot */
  1018. X
  1019. X/*==== l o c a l    d a t a ==================================================*/
  1020. X
  1021. X#define   GNUBUF    1024        /* buffer for gnuplot commands */
  1022. X#define   PIPEBUF   4096        /* size of pipe buffers */
  1023. X#define   CMDALLOC  4096        /* command buffer allocation increment (ints) */
  1024. X#define   ENVSIZE   2048        /* size of environment */ 
  1025. X#define   GNUPAGE   4096        /* size of gnuplot page in pixels (driver dependent) */
  1026. X
  1027. X#define   PAUSE_DLG 1           /* pause handled in dialog box */
  1028. X#define   PAUSE_BTN 2           /* pause handled by menu item */
  1029. X#define   PAUSE_GNU 3           /* pause handled by Gnuplot */
  1030. X
  1031. Xstatic HWND     hWndstart ;     /* used for errors in startup */
  1032. Xstatic ULONG    pidGnu=0L ;      /* gnuplot session id */
  1033. Xstatic ULONG    ppidGnu=0L ;      /* gnuplot pid */
  1034. Xstatic HPS      hpsScreen ;     /* screen pres. space */
  1035. X
  1036. Xstatic HSWITCH hSwitch = 0 ;    /* switching between windows */
  1037. Xstatic SWCNTRL swGnu ;
  1038. X
  1039. Xstatic BOOL     bLineTypes = FALSE ;
  1040. Xstatic BOOL     bLineThick = FALSE ;
  1041. Xstatic BOOL     bColours = TRUE ;
  1042. Xstatic BOOL     bShellPos = FALSE ;
  1043. Xstatic BOOL     bPlotPos = FALSE ;
  1044. Xstatic ULONG    ulPlotPos[4] ;
  1045. Xstatic ULONG    ulShellPos[4] ;
  1046. Xstatic char     szFontNameSize[FONTBUF] ;
  1047. Xstatic char     achPrinterName[128] = "" ;
  1048. Xstatic PRQINFO3 infPrinter = { "" } ;
  1049. Xstatic HMTX     semCommands ;
  1050. Xstatic HEV      semStartSeq ;   /* semaphore to start things in right sequence */
  1051. Xstatic HEV      semPause ;
  1052. Xstatic ULONG    ulPauseReply = 1 ;
  1053. Xstatic ULONG    ulPauseMode  = PAUSE_DLG ;
  1054. X
  1055. X            /* commands from gnuplot come via this ... */
  1056. X            
  1057. Xstatic HPIPE    hRead = 0L ; 
  1058. X           
  1059. X            /* stuff for screen-draw thread control */
  1060. X            
  1061. Xstatic BOOL     bExist ; 
  1062. Xstatic BOOL     bStopDraw ; 
  1063. Xstatic HEV      semDrawDone ;
  1064. Xstatic HEV      semStartDraw ;
  1065. X
  1066. X            /* command buffer */
  1067. X            
  1068. Xstatic int ncalloc = 0 ;
  1069. Xstatic int ic = 0 ;
  1070. Xstatic volatile int *commands = NULL ;
  1071. X
  1072. X/*==== f u n c t i o n s =====================================================*/
  1073. X
  1074. Xint             DoPrint( HWND ) ;
  1075. XMRESULT         WmClientCmdProc( HWND , ULONG, MPARAM, MPARAM ) ; 
  1076. Xvoid            ChangeCheck( HWND, USHORT, USHORT ) ;
  1077. XBOOL            QueryIni( HAB ) ;
  1078. Xstatic void     SaveIni( void ) ;
  1079. Xstatic void     ThreadDraw( void ) ;
  1080. Xstatic void     DoPaint( HWND, HPS ) ;
  1081. Xstatic void     Display( void ) ;
  1082. Xvoid            SelectFont( HPS, char *, short );
  1083. Xstatic void     ReadGnu( void ) ;
  1084. Xstatic void     WaitEnd( void ) ;
  1085. Xstatic void     AllocMore() ;
  1086. Xstatic int      BufRead( HFILE, void*, int, PULONG ) ;
  1087. Xint             GetNewFont( HWND, HPS ) ;
  1088. X
  1089. X
  1090. X/*==== c o d e ===============================================================*/
  1091. X
  1092. XMRESULT EXPENTRY DisplayClientWndProc(HWND hWnd, ULONG message, MPARAM mp1, MPARAM mp2)
  1093. X/*
  1094. X**  Window proc for main window
  1095. X**  -- passes most stuff to active child window via WmClientCmdProc
  1096. X**  -- passes DDE messages to DDEProc
  1097. X*/
  1098. X{
  1099. X    HDC     hdcScreen ;
  1100. X    SIZEL   sizlPage ;
  1101. X    TID     tidDraw, tidSpawn ;
  1102. X    char    *pp ;
  1103. X    ULONG   ulID ;
  1104. X    ULONG   ulFlag ;
  1105. X    char    szErrs[128] ;
  1106. X    
  1107. X    switch (message) {
  1108. X
  1109. X        case WM_CREATE:
  1110. X
  1111. X                // set initial values
  1112. X            ChangeCheck( hWnd, IDM_LINES_THICK, bLineThick?IDM_LINES_THICK:0 ) ;
  1113. X            ChangeCheck( hWnd, IDM_LINES_SOLID, bLineTypes?0:IDM_LINES_SOLID ) ;
  1114. X            ChangeCheck( hWnd, IDM_COLOURS, bColours?IDM_COLOURS:0 ) ;
  1115. X            hWndstart = hWnd ;  /* used in ReadGnu for errors */ 
  1116. X                // disable close from system menu (close only from gnuplot)
  1117. X            WinSendMsg( WinWindowFromID( WinQueryWindow( hWnd, QW_PARENT ), FID_SYSMENU ),
  1118. X                        MM_SETITEMATTR,
  1119. X                        MPFROM2SHORT(SC_CLOSE, TRUE ),
  1120. X                        MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED ) ) ;
  1121. X                // setup semaphores
  1122. X            DosCreateMutexSem( NULL, &semCommands, 0L, 0L ) ;
  1123. X            DosCreateEventSem( NULL, &semStartDraw, 0L, 0L ) ;
  1124. X            DosCreateEventSem( NULL, &semDrawDone, 0L, 0L ) ;
  1125. X            DosCreateEventSem( NULL, &semStartSeq, 0L, 0L ) ;
  1126. X            DosCreateEventSem( NULL, &semPause, 0L, 0L ) ;
  1127. X            bStopDraw = FALSE ;
  1128. X            bExist = TRUE ;
  1129. X                // create a dc and hps to draw on the screen
  1130. X            hdcScreen = WinOpenWindowDC( hWnd ) ;
  1131. X            sizlPage.cx = GNUPAGE ; sizlPage.cy = GNUPAGE ;
  1132. X            hpsScreen = GpiCreatePS( hab, hdcScreen, &sizlPage,
  1133. X                           PU_ARBITRARY|GPIT_MICRO|GPIA_ASSOC) ;
  1134. X                // spawn a thread to do the drawing
  1135. X            DosCreateThread( &tidDraw, (PFNTHREAD)ThreadDraw, 0L, 0L, 8192L ) ;
  1136. X                // then spawn server for GNUPLOT ...
  1137. X            DosCreateThread( &tidSpawn, (PFNTHREAD)ReadGnu, 0L, 0L, 8192L ) ;
  1138. X            DosWaitEventSem( semStartSeq, SEM_INDEFINITE_WAIT ) ;
  1139. X                // get details of command-line window
  1140. X            hSwitch = WinQuerySwitchHandle( 0, ppidGnu ) ;
  1141. X            WinQuerySwitchEntry( hSwitch, &swGnu ) ;
  1142. X                // set size of this window
  1143. X            WinSetWindowPos( WinQueryWindow( hWnd, QW_PARENT ), 
  1144. X                             HWND_TOP,
  1145. X                             ulShellPos[0],
  1146. X                             ulShellPos[1],
  1147. X                             ulShellPos[2],
  1148. X                             ulShellPos[3], 
  1149. X                             bShellPos?SWP_SIZE|SWP_MOVE|SWP_SHOW|SWP_ACTIVATE:SWP_SHOW|SWP_ACTIVATE ) ;
  1150. X                //  clear screen 
  1151. X            DosPostEventSem( semDrawDone ) ;  
  1152. X            break ;
  1153. X            
  1154. X
  1155. X        case WM_COMMAND:
  1156. X
  1157. X            return WmClientCmdProc( hWnd , message , mp1 , mp2 ) ;
  1158. X
  1159. X        case WM_CLOSE:
  1160. X
  1161. X            if( WinSendMsg( hWnd, WM_USER_PRINT_QBUSY, 0L, 0L ) != 0L ) {
  1162. X                WinMessageBox( HWND_DESKTOP,
  1163. X                               hWnd, 
  1164. X                               "Still printing - not closed",
  1165. X                               APP_NAME,
  1166. X                               0,
  1167. X                               MB_OK | MB_ICONEXCLAMATION ) ;
  1168. X                return 0L ;
  1169. X                }
  1170. X              return (WinDefWindowProc(hWnd, message, mp1, mp2));
  1171. X
  1172. X        case WM_PAINT:
  1173. X
  1174. X            DoPaint( hWnd, hpsScreen ) ;
  1175. X            break ;     
  1176. X
  1177. X        case WM_SIZE :
  1178. X            
  1179. X            WinInvalidateRect( hWnd, NULL, TRUE ) ;
  1180. X            break ;
  1181. X
  1182. X        case WM_PRESPARAMCHANGED:
  1183. X        
  1184. X            pp = malloc(FONTBUF) ;
  1185. X            if( WinQueryPresParam( hWnd, 
  1186. X                                   PP_FONTNAMESIZE, 
  1187. X                                   0, 
  1188. X                                   &ulID, 
  1189. X                                   FONTBUF, 
  1190. X                                   pp, 
  1191. X                                   QPF_NOINHERIT ) != 0L ) {
  1192. X                strcpy( szFontNameSize, pp ) ;
  1193. X                WinInvalidateRect( hWnd, NULL, TRUE ) ;
  1194. X                }
  1195. X            free(pp) ; 
  1196. X            break ;
  1197. X            
  1198. X        case WM_USER_PRINT_BEGIN:
  1199. X        case WM_USER_PRINT_OK :
  1200. X        case WM_USER_DEV_ERROR :
  1201. X        case WM_USER_PRINT_ERROR :
  1202. X        case WM_USER_PRINT_QBUSY :
  1203. X
  1204. X            return( PrintCmdProc( hWnd, message, mp1, mp2 ) ) ;
  1205. X
  1206. X        case WM_GNUPLOT:
  1207. X                // display the plot         
  1208. X            WinSetWindowPos( hwndFrame, HWND_TOP, 0,0,0,0, SWP_ACTIVATE|SWP_ZORDER ) ;
  1209. X            WinInvalidateRect( hWnd, NULL, TRUE ) ;
  1210. X            return 0L ;
  1211. X
  1212. X        case WM_PAUSEPLOT:
  1213. X                /* put pause message on screen, or enable 'continue' button */
  1214. X            if( ulPauseMode == PAUSE_DLG ) {
  1215. X                WinLoadDlg( HWND_DESKTOP,
  1216. X                            hWnd,
  1217. X                            (PFNWP)PauseMsgDlgProc,
  1218. X                            0L,
  1219. X                            IDD_PAUSEBOX,
  1220. X                            (char*)mp1 ) ; 
  1221. X                }
  1222. X            else { 
  1223. X                WinEnableMenuItem( WinWindowFromID( 
  1224. X                                   WinQueryWindow( hWnd, QW_PARENT ), FID_MENU ),
  1225. X                                   IDM_CONTINUE,
  1226. X                                   TRUE ) ;            
  1227. X                }
  1228. X            return 0L ;
  1229. X
  1230. X        case WM_PAUSEEND:
  1231. X            /* resume plotting */
  1232. X            ulPauseReply = (ULONG) mp1 ;
  1233. X            DosPostEventSem( semPause ) ;
  1234. X            return 0L ;
  1235. X    
  1236. X    default:         /* Passes it on if unproccessed    */
  1237. X        return (WinDefWindowProc(hWnd, message, mp1, mp2));
  1238. X    }
  1239. X    return (NULL);
  1240. X}
  1241. X
  1242. XMRESULT WmClientCmdProc(HWND hWnd, ULONG message, MPARAM mp1, MPARAM mp2)
  1243. X/*
  1244. X**   Handle client window command (menu) messages
  1245. X**   -- mostly passed on to active child window
  1246. X**
  1247. X*/
  1248. X    {
  1249. X    ULONG usDlg ;
  1250. X    extern HWND hApp ;
  1251. X    static ulPauseItem = IDM_PAUSEDLG ;
  1252. X
  1253. X    switch( (USHORT) SHORT1FROMMP( mp1 ) ) {
  1254. X                
  1255. X        case IDM_ABOUT :    /* show the 'About' box */
  1256. X             
  1257. X            WinDlgBox( HWND_DESKTOP,
  1258. X                       hWnd , 
  1259. X                       (PFNWP)About ,
  1260. X                       0L,
  1261. X                       ID_ABOUT, 
  1262. X                       NULL ) ;
  1263. X            break ;
  1264. X
  1265. X
  1266. X        case IDM_PRINT :    /* print plot */
  1267. X
  1268. X            if( SetupPrinter( hWnd, achPrinterName, &infPrinter ) )
  1269. X                WinPostMsg( hWnd, WM_USER_PRINT_BEGIN, (MPARAM)&infPrinter, 0L ) ; 
  1270. X            break ;
  1271. X
  1272. X        case IDM_PRINTSETUP :    /* select printer */
  1273. X
  1274. X            WinDlgBox( HWND_DESKTOP,
  1275. X                       hWnd ,
  1276. X                       (PFNWP)QPrintersDlgProc,
  1277. X                       0L,
  1278. X                       IDD_QUERYPRINT, 
  1279. X                       achPrinterName ) ;
  1280. X            break ;
  1281. X
  1282. X        case IDM_LINES_THICK:
  1283. X                // change line setting
  1284. X            bLineThick = !bLineThick ;
  1285. X            ChangeCheck( hWnd, IDM_LINES_THICK, bLineThick?IDM_LINES_THICK:0 ) ;
  1286. X            WinInvalidateRect( hWnd, NULL, TRUE ) ;
  1287. X            break ;
  1288. X
  1289. X        case IDM_LINES_SOLID:
  1290. X                // change line setting
  1291. X            bLineTypes = !bLineTypes ;
  1292. X            ChangeCheck( hWnd, IDM_LINES_SOLID, bLineTypes?0:IDM_LINES_SOLID ) ;
  1293. X            WinInvalidateRect( hWnd, NULL, TRUE ) ;
  1294. X            break ;
  1295. X
  1296. X        case IDM_COLOURS:
  1297. X                // change colour setting
  1298. X            bColours = !bColours ;        
  1299. X            ChangeCheck( hWnd, IDM_COLOURS, bColours?IDM_COLOURS:0 ) ;
  1300. X            WinInvalidateRect( hWnd, NULL, TRUE ) ;
  1301. X            break ;
  1302. X
  1303. X        case IDM_FONTS:
  1304. X        
  1305. X            if( GetNewFont( hWnd, hpsScreen ) ) 
  1306. X                WinInvalidateRect( hWnd, NULL, TRUE ) ;
  1307. X            break ;
  1308. X            
  1309. X        case IDM_SAVE :
  1310. X            SaveIni() ;
  1311. X            break ;
  1312. X            
  1313. X        case IDM_COMMAND:       /* go back to GNUPLOT command window */            
  1314. X            WinSwitchToProgram( hSwitch ) ;
  1315. X            break ;
  1316. X
  1317. X        case IDM_CONTINUE:
  1318. X            WinPostMsg( hWnd, WM_PAUSEEND, 1L, 0L ) ; 
  1319. X            WinEnableMenuItem( WinWindowFromID( 
  1320. X                               WinQueryWindow( hWnd, QW_PARENT ), FID_MENU ),
  1321. X                               IDM_CONTINUE,
  1322. X                               FALSE ) ;            
  1323. X            break ;
  1324. X            
  1325. X        case IDM_PAUSEGNU:  /* gnuplot handles pause */
  1326. X            ChangeCheck( hWnd, ulPauseItem, IDM_PAUSEGNU ) ;
  1327. X            ulPauseItem = IDM_PAUSEGNU ;
  1328. X            ulPauseMode = PAUSE_GNU ;
  1329. X            break ;
  1330. X            
  1331. X        case IDM_PAUSEDLG:  /* pause message in dlg box */
  1332. X            ChangeCheck( hWnd, ulPauseItem, IDM_PAUSEDLG ) ;
  1333. X            ulPauseItem = IDM_PAUSEDLG ;
  1334. X            ulPauseMode = PAUSE_DLG ;
  1335. X            break ;
  1336. X            
  1337. X        case IDM_PAUSEBTN:  /* pause uses menu button, no message */
  1338. X            ChangeCheck( hWnd, ulPauseItem, IDM_PAUSEBTN ) ;
  1339. X            ulPauseItem = IDM_PAUSEBTN ;
  1340. X            ulPauseMode = PAUSE_BTN ;
  1341. X            break ;
  1342. X          
  1343. X        case IDM_HELPFORHELP:
  1344. X            WinSendMsg(WinQueryHelpInstance(hWnd),
  1345. X                       HM_DISPLAY_HELP, 0L, 0L ) ;
  1346. X            return 0L ;
  1347. X
  1348. X        case IDM_EXTENDEDHELP:
  1349. X            WinSendMsg(WinQueryHelpInstance(hWnd),
  1350. X                        HM_EXT_HELP, 0L, 0L);
  1351. X            return 0L ;
  1352. X
  1353. X        case IDM_KEYSHELP:
  1354. X            WinSendMsg(WinQueryHelpInstance(hWnd),
  1355. X                       HM_KEYS_HELP, 0L, 0L);
  1356. X            return 0L ;
  1357. X
  1358. X        case IDM_HELPINDEX:
  1359. X            WinSendMsg(WinQueryHelpInstance(hWnd),
  1360. X                       HM_HELP_INDEX, 0L, 0L);
  1361. X            return 0L ;
  1362. X
  1363. X        default : 
  1364. X    
  1365. X            return WinDefWindowProc( hWnd, message, mp1, mp2 ) ;
  1366. X
  1367. X        }  
  1368. X    return( NULL ) ;
  1369. X    }                      
  1370. X
  1371. Xvoid ChangeCheck( HWND hWnd , USHORT wItem1 , USHORT wItem2 )
  1372. X/*
  1373. X**  Utility function:
  1374. X**
  1375. X**  move check mark from menu item 1 to item 2
  1376. X*/
  1377. X    {
  1378. X    HWND hMenu ;
  1379. X
  1380. X    hMenu = WinWindowFromID( WinQueryWindow( hWnd, QW_PARENT ), 
  1381. X                             FID_MENU ) ;            
  1382. X    if( wItem1 != 0 )
  1383. X        WinSendMsg( hMenu,
  1384. X                    MM_SETITEMATTR,
  1385. X                    MPFROM2SHORT( wItem1, TRUE ),
  1386. X                    MPFROM2SHORT( MIA_CHECKED, 0 ) ) ;
  1387. X    if( wItem2 != 0 )
  1388. X        WinSendMsg( hMenu,
  1389. X                    MM_SETITEMATTR,
  1390. X                    MPFROM2SHORT( wItem2, TRUE ),
  1391. X                    MPFROM2SHORT( MIA_CHECKED, MIA_CHECKED ) ) ;
  1392. X    }       
  1393. X
  1394. XBOOL QueryIni( HAB hab )
  1395. X/*
  1396. X** Query INI file
  1397. X*/
  1398. X    {
  1399. X    BOOL         bPos, bData ;
  1400. X    ULONG        ulOpts[4] ;
  1401. X    HINI         hini ;
  1402. X    ULONG        ulCB ;
  1403. X    char         *p ;
  1404. X    
  1405. X            // get default printer name    
  1406. X            
  1407. X    PrfQueryProfileString( HINI_PROFILE,
  1408. X                           "PM_SPOOLER",
  1409. X                           "PRINTER",
  1410. X                           ";",
  1411. X                           achPrinterName,
  1412. X                           (long) sizeof achPrinterName ) ;
  1413. X    if( (p=strchr( achPrinterName, ';' )) != NULL ) *p = '\0' ;
  1414. X    
  1415. X            // read gnuplot ini file
  1416. X
  1417. X    hini = PrfOpenProfile( hab, GNUINI ) ;
  1418. X    ulCB = sizeof( ulShellPos ) ;
  1419. X    bPos = PrfQueryProfileData( hini, APP_NAME, INISHELLPOS, &ulShellPos, &ulCB ) ;
  1420. X    ulCB = sizeof( ulOpts ) ;
  1421. X    bData = PrfQueryProfileData( hini, APP_NAME, INIOPTS, &ulOpts, &ulCB ) ;
  1422. X    if( bData ) {
  1423. X        bLineTypes = (BOOL)ulOpts[0] ;
  1424. X        bLineThick = (BOOL)ulOpts[1] ;
  1425. X        bColours = (BOOL)ulOpts[2] ;
  1426. X        ulPauseMode = ulOpts[3] ;
  1427. X        }
  1428. X    else {
  1429. X        bLineTypes = FALSE ;  /* default values */
  1430. X        bLineThick = FALSE ;
  1431. X        bColours = TRUE ;
  1432. X        ulPauseMode = 1 ;
  1433. X        }
  1434. X    PrfQueryProfileString( hini, APP_NAME, INIFONT, INITIAL_FONT, 
  1435. X                                 szFontNameSize, FONTBUF ) ;
  1436. X    PrfCloseProfile( hini ) ;
  1437. X    bShellPos = bPos ;
  1438. X    return bPos ;
  1439. X    }
  1440. X
  1441. Xstatic void SaveIni( )
  1442. X/*
  1443. X** save data in ini file
  1444. X*/
  1445. X    {
  1446. X    SWP swp ;
  1447. X    HINI  hini ;
  1448. X    ULONG ulOpts[4] ;
  1449. X    
  1450. X    hini = PrfOpenProfile( hab, GNUINI ) ;
  1451. X    WinQueryWindowPos( hwndFrame, &swp ) ;
  1452. X    ulPlotPos[0] = swp.x ;
  1453. X    ulPlotPos[1] = swp.y ;
  1454. X    ulPlotPos[2] = swp.cx ;
  1455. X    ulPlotPos[3] = swp.cy ;
  1456. X    PrfWriteProfileData( hini, APP_NAME, INISHELLPOS, &ulPlotPos, sizeof(ulPlotPos) ) ;
  1457. X/*
  1458. X    WinQueryWindowPos( swGnu.hwnd, &swp ) ;
  1459. X    ulPlotPos[0] = swp.x ;
  1460. X    ulPlotPos[1] = swp.y ;
  1461. X    ulPlotPos[2] = swp.cx ;
  1462. X    ulPlotPos[3] = swp.cy ;
  1463. X    PrfWriteProfileData( hini, APP_NAME, INIPLOTPOS, &ulPlotPos, sizeof(ulPlotPos) ) ;
  1464. X*/
  1465. X    ulOpts[0] = (ULONG)bLineTypes ;
  1466. X    ulOpts[1] = (ULONG)bLineThick ; 
  1467. X    ulOpts[2] = (ULONG)bColours ;
  1468. X    ulOpts[3] = ulPauseMode ; 
  1469. X    PrfWriteProfileData( hini, APP_NAME, INIOPTS, &ulOpts, sizeof(ulOpts) ) ;
  1470. X    PrfWriteProfileString( hini, APP_NAME, INIFONT, szFontNameSize ) ;
  1471. X    PrfCloseProfile( hini ) ;
  1472. X    }
  1473. X
  1474. Xstatic void DoPaint( HWND hWnd, HPS hps  ) 
  1475. X/*
  1476. X**  Paint the screen with current data 
  1477. X*/
  1478. X    {
  1479. X    RECTL rectClient ;
  1480. X    ULONG ulCount ;    
  1481. X    bStopDraw = TRUE ;    // stop any drawing in progress and wait for 
  1482. X                          // thread to signal completion 
  1483. X    DosWaitEventSem( semDrawDone, SEM_INDEFINITE_WAIT ) ;
  1484. X    DosResetEventSem( semDrawDone, &ulCount ) ;
  1485. X    WinBeginPaint( hWnd , hps, NULL ) ;
  1486. X    DosPostEventSem( semStartDraw ) ;  // start drawing
  1487. X    }
  1488. X
  1489. Xstatic void ThreadDraw( )
  1490. X/*
  1491. X**  Thread to draw plot
  1492. X*/
  1493. X    {
  1494. X    HAB  hab ;
  1495. X    RECTL rectClient ;
  1496. X    ULONG ulCount ;
  1497. X
  1498. X        /* initialize and wait until ready to draw */
  1499. X    
  1500. X    hab = WinInitialize( 0 ) ;
  1501. X
  1502. X        /* ok - draw until window is destroyed */
  1503. X
  1504. X    while( bExist )  {
  1505. X
  1506. X                // indicate access to window 
  1507. X        DosWaitEventSem( semStartDraw, SEM_INDEFINITE_WAIT ) ;
  1508. X        DosResetEventSem( semStartDraw, &ulCount ) ;
  1509. X
  1510. X                // will be set TRUE if we decide to stop in the middle, but now
  1511. X        bStopDraw = FALSE ;         
  1512. X        
  1513. X        GpiResetPS( hpsScreen, GRES_ALL ) ;        
  1514. X        WinQueryWindowRect( hApp, (PRECTL)&rectClient ) ;
  1515. X        GpiSetPageViewport( hpsScreen, &rectClient ) ;
  1516. X
  1517. X        WinFillRect( hpsScreen, &rectClient, CLR_WHITE ) ;
  1518. X
  1519. X        ScalePS( hpsScreen, &rectClient, 0 ) ;
  1520. X
  1521. X        PlotThings( hpsScreen, 0L ) ;
  1522. X                // ok, say that we did it
  1523. X
  1524. X        WinEndPaint( hpsScreen ) ;
  1525. X        DosPostEventSem( semDrawDone ) ;
  1526. X        }
  1527. X   
  1528. X    WinTerminate( hab ) ;
  1529. X    }
  1530. X
  1531. X
  1532. Xenum JUSTIFY { LEFT, CENTRE, RIGHT } jmode;
  1533. X
  1534. Xvoid PlotThings( HPS hps, long lColour ) 
  1535. X/*
  1536. X**  Plot a spectrum and related graphs on the designated presentation space
  1537. X**
  1538. X**  Input:
  1539. X**          HPS hps         -- presentation space handle of plot ps
  1540. X**          long lColour    -- number of physical colours, used mainly by
  1541. X**                             printer drivers to set black & white mode.
  1542. X**                             If 0, assume screen display
  1543. X**
  1544. X**  Note: use semaphore to prevent access to command list while
  1545. X**        pipe thread is reallocating the list.
  1546. X*/
  1547. X    {
  1548. X    int i, lt, ta, col, sl, n, x, y, cx, cy, width ;
  1549. X    int icnow ;
  1550. X    int cmd ;
  1551. X    char *str, *buf ;
  1552. X    long sw ;
  1553. X    POINTL ptl ;
  1554. X    POINTL aptl[4] ;    
  1555. X    FONTMETRICS fm ;
  1556. X    HDC hdc ;
  1557. X    long lVOffset ;
  1558. X    long yDeviceRes ;
  1559. X    long lCurCol ;
  1560. X    long lOldLine = 0 ;
  1561. X    BOOL bBW ;
  1562. X    GRADIENTL grdl ;
  1563. X    BOOL bHorz = TRUE ;
  1564. X    SIZEF sizHor, sizVer ;
  1565. X        /* sometime, make these user modifiable... */
  1566. X    static long lLineTypes[7] = { LINETYPE_SOLID,
  1567. X                                  LINETYPE_SHORTDASH,
  1568. X                                  LINETYPE_DOT,
  1569. X                                  LINETYPE_DASHDOT,
  1570. X                                  LINETYPE_LONGDASH,
  1571. X                                  LINETYPE_DOUBLEDOT,
  1572. X                                  LINETYPE_DASHDOUBLEDOT } ;
  1573. X    static long lCols[15] =     { CLR_BLACK,
  1574. X                                  CLR_DARKGRAY,
  1575. X                                  CLR_BLUE,
  1576. X                                  CLR_RED,
  1577. X                                  CLR_GREEN,
  1578. X                                  CLR_CYAN,
  1579. X                                  CLR_PINK,
  1580. X                                  CLR_YELLOW,
  1581. X                                  CLR_DARKBLUE,
  1582. X                                  CLR_DARKRED,
  1583. X                                  CLR_DARKGREEN,
  1584. X                                  CLR_DARKCYAN,
  1585. X                                  CLR_DARKPINK,
  1586. X                                  CLR_BROWN,
  1587. X                                  CLR_PALEGRAY } ;
  1588. X
  1589. X    if( commands == NULL ) return ;
  1590. X
  1591. X        /* check for colourless devices */
  1592. X
  1593. X    if( lColour== 1 || lColour == 2 ) bBW = TRUE ;
  1594. X    else bBW = FALSE ;
  1595. X
  1596. X        /* get vertical offset for horizontal text strings */
  1597. X        /* (0.5 em height, so string in vertically centered
  1598. X           about plot position */
  1599. X
  1600. X    GpiQueryFontMetrics( hps, sizeof( FONTMETRICS ), &fm ) ;
  1601. X    lVOffset = fm.lEmHeight ;
  1602. X
  1603. X    
  1604. X   /* loop over accumulated commands from inboard driver */
  1605. X
  1606. X    DosRequestMutexSem( semCommands, SEM_INDEFINITE_WAIT ) ;
  1607. X
  1608. X    GpiSetLineWidth( hps, bLineThick?LINEWIDTH_THICK:LINEWIDTH_NORMAL ) ;
  1609. X    for( i=0; bExist && i<ic; ) {
  1610. X
  1611. X            if( bStopDraw ) break ;
  1612. X
  1613. X            cmd = commands[i++];
  1614. X
  1615. X      /*   PM_vector(x,y) - draw vector  */
  1616. X            if (cmd == 'V') { 
  1617. X                 ptl.x = (LONG)commands[i++] ; ptl.y = (LONG)commands[i++] ;
  1618. X                 GpiLine( hps, &ptl ) ;
  1619. X             }
  1620. X
  1621. X      /*   PM_move(x,y) - move  */
  1622. X            else if (cmd == 'M')  {
  1623. X                ptl.x = (LONG)commands[i++] ; ptl.y = (LONG)commands[i++] ;
  1624. X                GpiMove( hps, &ptl ) ;
  1625. X                }
  1626. X        
  1627. X      /*   PM_put_text(x,y,str) - draw text   */
  1628. X            else if (cmd == 'T') { 
  1629. X                x = commands[i++] ;
  1630. X                y = commands[i++] ;
  1631. X            str = (char*)&commands[i] ; 
  1632. X            sl = strlen(str) ;
  1633. X            i += 1+sl/sizeof(int) ;
  1634. X                lCurCol = GpiQueryColor( hps ) ;
  1635. X                GpiSetColor( hps, CLR_BLACK ) ;
  1636. X                GpiQueryTextBox( hps, (LONG)strlen( str ), str, 4L, aptl ) ;
  1637. X                if( bHorz ) sw = aptl[3].x ;
  1638. X                else sw = aptl[3].y ;
  1639. X                switch(jmode) {
  1640. X                case LEFT:   sw = 0;     break;
  1641. X                case CENTRE: sw = -sw/2; break;
  1642. X                case RIGHT:  sw = -sw;   break;
  1643. X                    }
  1644. X                if( bHorz ) {
  1645. X                    ptl.x = (LONG)(x+sw) ; ptl.y = (LONG)(y-lVOffset/4) ;
  1646. X                    }
  1647. X                else {
  1648. X                    ptl.x = (LONG)x ; ptl.y = (LONG)(y+sw) ;
  1649. X                    }
  1650. X                GpiCharStringAt( hps, &ptl, (LONG) strlen( str ) , str ) ;
  1651. X                GpiSetColor( hps, lCurCol ) ;
  1652. X            }
  1653. X
  1654. X      /*   PM_justify_text(mode) - set text justification mode  */
  1655. X            else if (cmd == 'J') 
  1656. X                jmode = commands[i++] ;
  1657. X
  1658. X      /*   PM_linetype(type) - set line type  */
  1659. X      /* mapped to colour */
  1660. X            else if (cmd == 'L') { 
  1661. X                lt = commands[i++] ;
  1662. X        /* linetype = -2 axes, -1 border, 0 arrows, all to 0 */
  1663. X            col = lt ;
  1664. X                if( lt == -1 ) GpiSetLineWidth( hps, LINEWIDTH_NORMAL ) ;
  1665. X                else GpiSetLineWidth( hps, bLineThick?LINEWIDTH_THICK:LINEWIDTH_NORMAL ) ;
  1666. X                if( lt < 0 ) lt = 0 ;
  1667. X            lt = (lt%8);
  1668. X            col = (col+2)%16 ;
  1669. X                if( bLineTypes || bBW ) {
  1670. X                    GpiSetLineType( hps, lLineTypes[lt] ) ;
  1671. X                    }
  1672. X                if( !bBW )  /* maintain some flexibility here in case we don't want
  1673. X                           the model T option */ 
  1674. X                    if( bColours ) GpiSetColor( hps, lCols[col] ) ;
  1675. X                    else GpiSetColor( hps, CLR_BLACK ) ;
  1676. X                }
  1677. X
  1678. X            else if (cmd == 'D') { /* point/dot mode - may need colour change */
  1679. X                lt = commands[i++] ;  /* 1: enter point mode, 0: exit */
  1680. X                if( bLineTypes || bBW ) {
  1681. X                    if( lt == 1 ) lOldLine = GpiSetLineType( hps, lLineTypes[0] ) ;
  1682. X                    else GpiSetLineType( hps, lOldLine ) ;
  1683. X                    }
  1684. X                }
  1685. X
  1686. X      /*   PM_text_angle(ang) - set text angle, 0 horz, 1 vert  */
  1687. X            else if (cmd == 'A') { 
  1688. X                ta = commands[i++] ;
  1689. X                if( ta == 0 ) {
  1690. X                    grdl.x = 0L ; grdl.y = 0L ;
  1691. X                    GpiSetCharAngle( hps, &grdl ) ;
  1692. X                    if( !bHorz ) {
  1693. X                        GpiQueryCharBox( hps, &sizVer ) ;
  1694. X                        sizHor.cx = sizVer.cy ; sizHor.cy = sizVer.cx ;
  1695. X                        GpiSetCharBox( hps, &sizHor ) ;
  1696. X                        bHorz = TRUE ;
  1697. X                        }
  1698. X                    }
  1699. X                else if( ta == 1 ) {
  1700. X                    grdl.x = 0L ; grdl.y = 1L ;
  1701. X                    GpiSetCharAngle( hps, &grdl ) ;
  1702. X                    if( bHorz ) {
  1703. X                        GpiQueryCharBox( hps, &sizHor ) ;
  1704. X                        sizVer.cx = sizHor.cy ; sizVer.cy = sizHor.cx ;
  1705. X                        GpiSetCharBox( hps, &sizVer ) ;
  1706. X                        bHorz = FALSE ;
  1707. X                        }
  1708. X                    }
  1709. X                else continue ;            
  1710. X                }
  1711. X            }
  1712. X        DosReleaseMutexSem( semCommands ) ;
  1713. X    }
  1714. X    
  1715. Xshort ScalePS( HPS hps, PRECTL prect, USHORT usFlags )
  1716. X/*
  1717. X**  Get a font to use
  1718. X**  Scale the plot area to world coords for subsequent plotting
  1719. X*/
  1720. X    {
  1721. X    RECTL rectView, rectClient ;
  1722. X    SIZEL sizePage ;
  1723. X    static char *szFontName ;
  1724. X    static short shFontSize ;
  1725. X        
  1726. X    rectClient = *prect ;
  1727. X    sizePage.cx = GNUPAGE ; 
  1728. X    sizePage.cy = GNUPAGE ; 
  1729. X
  1730. X    sscanf( szFontNameSize, "%d", &shFontSize ) ;
  1731. X    szFontName = strchr( szFontNameSize, '.' ) + 1 ;
  1732. X    rectView.xLeft = 0L ;
  1733. X    rectView.xRight = sizePage.cx ;
  1734. X    rectView.yBottom = 0L ; rectView.yTop = sizePage.cy ;
  1735. X    GpiSetPS( hps, &sizePage, PU_ARBITRARY ) ;
  1736. X    GpiSetPageViewport( hps, &rectClient ) ;
  1737. X    SelectFont( hps, szFontName, shFontSize ) ;
  1738. X    GpiSetGraphicsField( hps, &rectView ) ;
  1739. X    return 0 ;
  1740. X    }
  1741. X
  1742. Xvoid SelectFont( HPS hps, char *szFont, short shPointSize )
  1743. X/*
  1744. X**  Select a named and sized outline (adobe) font
  1745. X*/
  1746. X    {
  1747. X     HDC         hdc ;
  1748. X     static FATTRS fat ;
  1749. X     LONG   xDeviceRes, yDeviceRes ;
  1750. X     POINTL ptlFont ;
  1751. X     SIZEF  sizfx ;
  1752. X     static LONG lcid = 0L ;
  1753. X
  1754. X     fat.usRecordLength  = sizeof fat ;
  1755. X     fat.fsSelection     = 0 ;
  1756. X     fat.lMatch          = 0 ;
  1757. X     fat.idRegistry      = 0 ;
  1758. X     fat.usCodePage      = GpiQueryCp (hps) ;
  1759. X     fat.lMaxBaselineExt = 0 ;
  1760. X     fat.lAveCharWidth   = 0 ;
  1761. X     fat.fsType          = 0 ;
  1762. X     fat.fsFontUse       = FATTR_FONTUSE_OUTLINE |
  1763. X                           FATTR_FONTUSE_TRANSFORMABLE ;
  1764. X
  1765. X     strcpy (fat.szFacename, szFont) ;
  1766. X
  1767. X     if( lcid == 0L ) lcid = 1L ;
  1768. X     else {
  1769. X        GpiSetCharSet( hps, 0L) ;
  1770. X        GpiDeleteSetId( hps, lcid ) ;
  1771. X        }
  1772. X     GpiCreateLogFont (hps, NULL, lcid, &fat) ;
  1773. X     GpiSetCharSet( hps, lcid ) ;
  1774. X
  1775. X     hdc = GpiQueryDevice (hps) ;
  1776. X
  1777. X     DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION, 1L, &xDeviceRes) ;
  1778. X     DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION,   1L, &yDeviceRes) ;
  1779. X
  1780. X                         // Find desired font size in pixels
  1781. X
  1782. X     ptlFont.x = 254L * (long)shPointSize * xDeviceRes / 720000L ;
  1783. X     ptlFont.y = 254L * (long)shPointSize * yDeviceRes / 720000L ;
  1784. X
  1785. X                         // Convert to page units
  1786. X
  1787. X     GpiConvert (hps, CVTC_DEVICE, CVTC_PAGE, 1L, &ptlFont) ;
  1788. X
  1789. X                         // Set the character box
  1790. X
  1791. X     sizfx.cx = MAKEFIXED (ptlFont.x, 0) ;
  1792. X     sizfx.cy = MAKEFIXED (ptlFont.y, 0) ;
  1793. X
  1794. X     GpiSetCharBox (hps, &sizfx) ;
  1795. X    }
  1796. X
  1797. Xstatic void ReadGnu()
  1798. X/*
  1799. X** Thread to read plot commands from  GNUPLOT pm driver.
  1800. X** Opens named pipe, then clears semaphore to allow GNUPLOT driver to proceed.
  1801. X** Reads commands and builds a command list.
  1802. X*/
  1803. X    {
  1804. X    char *szEnv ;
  1805. X    char *szFileBuf ;
  1806. X    ULONG rc; 
  1807. X    USHORT usErr ;
  1808. X    ULONG cbR ;
  1809. X    STARTDATA start ;
  1810. X    USHORT i ;
  1811. X    PID ppid ;
  1812. X    unsigned char buff[2] ;
  1813. X    int len ;
  1814. X    HEV hev ;
  1815. X    static char *szPauseText = NULL ;
  1816. X    ULONG ulPause ;
  1817. X    char *pszPipeName, *pszSemName ;
  1818. X    
  1819. X#ifdef USEOWNALLOC
  1820. X    DosAllocMem( &commands, 64*1024*1024, PAG_READ|PAG_WRITE ) ;
  1821. X#endif
  1822. X
  1823. X    DosEnterCritSec() ;
  1824. X    pszPipeName = malloc( 256 ) ;
  1825. X    pszSemName  = malloc( 256 ) ;
  1826. X    DosExitCritSec() ;
  1827. X    strcpy( pszPipeName, "\\pipe\\" ) ;
  1828. X    strcpy( pszSemName, "\\sem32\\" ) ;
  1829. X    strcat( pszPipeName, szIPCName ) ;
  1830. X    strcat( pszSemName, szIPCName ) ;
  1831. X
  1832. X            /* open a named pipe for communication with gnuplot */
  1833. X    rc = DosCreateNPipe( pszPipeName,
  1834. X                         &hRead, 
  1835. X                         NP_ACCESS_DUPLEX|NP_NOINHERIT|NP_NOWRITEBEHIND ,
  1836. X                         1|NP_WAIT|NP_READMODE_MESSAGE|NP_TYPE_MESSAGE,
  1837. X                         PIPEBUF,
  1838. X                         PIPEBUF,
  1839. X                         0xFFFFFFFF) ;
  1840. X    hev = 0 ;       /* OK, gnuplot can try to open npipe ... */
  1841. X    DosOpenEventSem( pszSemName, &hev ) ;
  1842. X    DosPostEventSem( hev ) ;
  1843. X    
  1844. X
  1845. X    
  1846. X        /* attach to gnuplot */
  1847. X
  1848. X    if( DosConnectNPipe( hRead ) == 0L ) {
  1849. X
  1850. X        /* store graphics commands */
  1851. X        /* use semaphore to prevent problems with drawing while reallocating
  1852. X           the command buffers */
  1853. X
  1854. X        DosRead( hRead, &ppidGnu, 4, &cbR ) ;
  1855. X        DosPostEventSem( semStartSeq ) ;         /* once we've got pidGnu */
  1856. X
  1857. X
  1858. X        while (1) {
  1859. X        
  1860. X            usErr=BufRead(hRead,buff, 1, &cbR) ;
  1861. X            if( usErr != 0 ) break ;
  1862. X            switch( *buff ) {
  1863. X                case 'G' :    /* enter graphics mode */
  1864. X                    /* wait for access to command list and lock it */
  1865. X                    DosRequestMutexSem( semCommands, SEM_INDEFINITE_WAIT ) ;
  1866. X                    DosEnterCritSec() ;
  1867. X#ifdef USEOWNALLOC
  1868. X                    if( ncalloc > 0 ) {
  1869. X                        DosSetMem( commands, ncalloc*sizeof(int), PAG_DECOMMIT ) ;
  1870. X#else
  1871. X                       if (commands!=NULL) {    // delete all old commands and prepare for new
  1872. X                        free(commands);
  1873. X#endif
  1874. X                        }
  1875. X                    ic = 0 ;
  1876. X                    ncalloc = CMDALLOC ;
  1877. X#ifdef USEOWNALLOC
  1878. X                    DosSetMem( commands, ncalloc*sizeof(int), PAG_COMMIT|PAG_DEFAULT ) ;
  1879. X#else
  1880. X                    commands = (int*)malloc(ncalloc*sizeof(int)) ;
  1881. X#endif
  1882. X                    DosExitCritSec() ;
  1883. X                    DosReleaseMutexSem( semCommands ) ;
  1884. X                    break ;
  1885. X                    
  1886. X                case 'E' :     /* leave graphics mode (graph completed) */
  1887. X                    Display() ; /* plot graph */
  1888. X                    break ;
  1889. X                    
  1890. X                case 'R' :
  1891. X                    /* gnuplot has reset drivers, we do nothing */
  1892. X                    break ;
  1893. X
  1894. X                case 'M' :   /* move */
  1895. X                case 'V' :   /* draw vector */
  1896. X                    commands[ ic++ ] = (int)*buff ; 
  1897. X                    if( ic+2 >= ncalloc ) AllocMore() ;
  1898. X                    BufRead(hRead,&commands[ic], 2*sizeof(int), &cbR) ;
  1899. X                    ic+=2 ;
  1900. X                    break ;
  1901. X                  
  1902. X                case 'P' :   /* pause */
  1903. X                    BufRead(hRead,&len, sizeof(int), &cbR) ;
  1904. X                    len = (len+sizeof(int)-1)/sizeof(int) ;
  1905. X                    if( len > 0 ){  /* get pause text */
  1906. X                        szPauseText = malloc( len*sizeof(int) ) ;
  1907. X                        BufRead(hRead,szPauseText, len*sizeof(int), &cbR) ;
  1908. X                        }
  1909. X                    if( ulPauseMode != PAUSE_GNU ) {
  1910. X                             /* pause and wait for semaphore to be cleared */
  1911. X                        DosResetEventSem( semPause, &ulPause ) ;
  1912. X                        WinPostMsg( hApp, WM_PAUSEPLOT, (MPARAM) szPauseText, 0L ) ;
  1913. X                        DosWaitEventSem( semPause, SEM_INDEFINITE_WAIT ) ;
  1914. X                        }
  1915. X                    else { /* gnuplot handles pause */
  1916. X                        ulPauseReply = 2 ;
  1917. X                        }
  1918. X                    if( szPauseText != NULL ) free( szPauseText ) ;
  1919. X                    szPauseText = NULL ;
  1920. X                             /* reply to gnuplot so it can continue */
  1921. X                    DosWrite( hRead, &ulPauseReply, sizeof(int), &cbR ) ;
  1922. X                    break ; 
  1923. X                       
  1924. X                case 'T' :   /* write text */
  1925. X                    commands[ ic++ ] = (int)*buff ; 
  1926. X                    if( ic+1 >= ncalloc ) AllocMore() ;
  1927. X                        /* read x, y, len */
  1928. X                    BufRead(hRead,&commands[ic++], sizeof(int), &cbR) ;
  1929. X                    BufRead(hRead,&commands[ic++], sizeof(int), &cbR) ;
  1930. X                    BufRead(hRead,&len, sizeof(int), &cbR) ;
  1931. X                    if( ic+1+((len+sizeof(int)-1)/sizeof(int)) >= ncalloc ) AllocMore() ;
  1932. X                    BufRead(hRead,&commands[ic], len, &cbR) ;
  1933. X                    if( len == 0 ) len = 1 ;
  1934. X                    ic += (len+sizeof(int)-1)/sizeof(int) ;
  1935. X                    break ;
  1936. X                    
  1937. X                case 'J' :   /* justify */
  1938. X                case 'A' :   /* text angle */
  1939. X                case 'L' :   /* line type */
  1940. X                case 'D' :   /* points mode */
  1941. X                
  1942. X                    commands[ ic++ ] = (int)*buff ; 
  1943. X                    if( ic+1 >= ncalloc ) AllocMore() ;
  1944. X                    BufRead(hRead,&commands[ic++], sizeof(int), &cbR) ;
  1945. X                    break ;
  1946. X
  1947. X                 default :  /* should handle error */
  1948. X                    break ;
  1949. X                 }
  1950. X             }
  1951. X        }
  1952. X    DosEnterCritSec() ;
  1953. X    free( szFileBuf ) ;
  1954. X    free( szEnv ) ;
  1955. X    DosExitCritSec() ;
  1956. X    pidGnu = 0 ; /* gnuplot has shut down (?) */
  1957. X    WinPostMsg( hApp, WM_CLOSE, 0L, 0L ) ;    
  1958. X    }
  1959. X
  1960. Xstatic int BufRead( HFILE hfile, void *buf, int nBytes, ULONG *pcbR )
  1961. X/*
  1962. X** pull next plot command out of buffer read from GNUPLOT
  1963. X*/
  1964. X    {
  1965. X    ULONG ulR, ulRR ;
  1966. X    static char buffer[GNUBUF] ;
  1967. X    static char *pbuffer = buffer+GNUBUF, *ebuffer = buffer+GNUBUF ;
  1968. X    
  1969. X    for( ; nBytes > 0 ; nBytes-- ) {
  1970. X        if( pbuffer >= ebuffer ) {
  1971. X            ulR = GNUBUF ;
  1972. X            DosRead( hfile, buffer, ulR, &ulRR ) ;
  1973. X            pbuffer = buffer ;
  1974. X            ebuffer = pbuffer+ulRR ;
  1975. X            }
  1976. X        *(char*)buf++ = *pbuffer++ ;
  1977. X        }
  1978. X    return 0L ;
  1979. X    } 
  1980. X
  1981. Xstatic void AllocMore()
  1982. X/*
  1983. X**  Allocate more memory for plot commands
  1984. X*/
  1985. X    {
  1986. X    DosRequestMutexSem( semCommands, SEM_INDEFINITE_WAIT ) ;
  1987. X    DosEnterCritSec() ;
  1988. X#ifdef USEOWNALLOC
  1989. X    DosSetMem( commands+ncalloc, CMDALLOC*sizeof(int), PAG_COMMIT|PAG_DEFAULT ) ;
  1990. X#endif
  1991. X    ncalloc = ncalloc + CMDALLOC ;
  1992. X#ifndef USEOWNALLOC
  1993. X    commands = (int*)realloc(commands, ncalloc*sizeof(int)) ;
  1994. X#endif
  1995. X    DosExitCritSec() ;
  1996. X    DosReleaseMutexSem( semCommands ) ;
  1997. X    }
  1998. X
  1999. Xstatic void Display()
  2000. X/*
  2001. X**  Display gnuplot results 
  2002. X**  -- must post message as this thread is not drawing thread
  2003. X*/
  2004. X    {
  2005. X    WinPostMsg( hApp, WM_GNUPLOT, 0L, 0L ) ;    
  2006. X    }
  2007. X
  2008. Xint GetNewFont( HWND hwnd, HPS hps ) 
  2009. X/*
  2010. X** Get a new font using standard font dialog
  2011. X*/
  2012. X    {
  2013. X    static FONTDLG pfdFontdlg;      /* Font dialog info structure */
  2014. X    static int i1 =1 ;
  2015. X    static int     iSize ;
  2016. X    char szPtList[64] ;
  2017. X    HWND    hwndFontDlg;     /* Font dialog window handle */
  2018. X    char    *p ; 
  2019. X    char szFamilyname[FACESIZE];
  2020. X    if( i1 ) {
  2021. X        strcpy( pfdFontdlg.fAttrs.szFacename, strchr( szFontNameSize, '.' ) + 1 ) ;
  2022. X        strcpy( szFamilyname, strchr( szFontNameSize, '.' ) + 1 ) ;
  2023. X        sscanf( szFontNameSize, "%d", &iSize ) ;
  2024. X        memset(&pfdFontdlg, 0, sizeof(FONTDLG));
  2025. X        pfdFontdlg.cbSize = sizeof(FONTDLG);
  2026. X        pfdFontdlg.hpsScreen = hps;
  2027. X /*   szFamilyname[0] = 0;*/
  2028. X        pfdFontdlg.pszFamilyname = szFamilyname;
  2029. X        pfdFontdlg.usFamilyBufLen = FACESIZE;
  2030. X        pfdFontdlg.fl = FNTS_HELPBUTTON | FNTS_CENTER | FNTS_VECTORONLY | FNTS_INITFROMFATTRS ; 
  2031. X        pfdFontdlg.clrFore = CLR_BLACK;
  2032. X        pfdFontdlg.clrBack = CLR_WHITE;
  2033. X        pfdFontdlg.usWeight = 5 ;
  2034. X        pfdFontdlg.fAttrs.usCodePage = 0;
  2035. X        i1=0; 
  2036. X        }
  2037. X    sprintf( szPtList, "%d 8 10 12 14 18 24", iSize ) ;
  2038. X    pfdFontdlg.pszPtSizeList = szPtList ;
  2039. X    pfdFontdlg.fxPointSize = MAKEFIXED(iSize,0); 
  2040. X    hwndFontDlg = WinFontDlg(HWND_DESKTOP, hwnd, &pfdFontdlg);
  2041. X    if (hwndFontDlg && (pfdFontdlg.lReturn == DID_OK)) {
  2042. X        iSize = FIXEDINT( pfdFontdlg.fxPointSize ) ;
  2043. X        sprintf( szFontNameSize, "%d.%s", iSize, pfdFontdlg.fAttrs.szFacename ) ;
  2044. X        return 1 ;
  2045. X        }
  2046. X    else return 0 ;
  2047. X    }
  2048. END_OF_FILE
  2049.   if test 37236 -ne `wc -c <'gnuplot/os2/gclient.c'`; then
  2050.     echo shar: \"'gnuplot/os2/gclient.c'\" unpacked with wrong size!
  2051.   fi
  2052.   # end of 'gnuplot/os2/gclient.c'
  2053. fi
  2054. if test -f 'gnuplot/specfun.c' -a "${1}" != "-c" ; then 
  2055.   echo shar: Will not clobber existing file \"'gnuplot/specfun.c'\"
  2056. else
  2057.   echo shar: Extracting \"'gnuplot/specfun.c'\" \(20743 characters\)
  2058.   sed "s/^X//" >'gnuplot/specfun.c' <<'END_OF_FILE'
  2059. X#ifndef lint
  2060. Xstatic char *RCSid = "$Id: specfun.c%v 3.50.1.9 1993/08/05 05:38:59 woo Exp $";
  2061. X#endif
  2062. X
  2063. X
  2064. X/** GNUPLOT - specfun.c
  2065. X *
  2066. X * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley,
  2067. X *                                              Jos van der Woude
  2068. X *
  2069. X * Permission to use, copy, and distribute this software and its
  2070. X * documentation for any purpose with or without fee is hereby granted,
  2071. X * provided that the above copyright notice appear in all copies and
  2072. X * that both that copyright notice and this permission notice appear
  2073. X * in supporting documentation.
  2074. X *
  2075. X * Permission to modify the software is granted, but not the right to
  2076. X * distribute the modified code.  Modifications are to be distributed
  2077. X * as patches to released version.
  2078. X *
  2079. X * This software is provided "as is" without express or implied warranty.
  2080. X *
  2081. X *
  2082. X * AUTHORS
  2083. X *
  2084. X *   Original Software:
  2085. X *   Jos van der Woude, jvdwoude@hut.nl
  2086. X *
  2087. X * There is a mailing list for gnuplot users. Note, however, that the
  2088. X * newsgroup 
  2089. X *    comp.graphics.gnuplot 
  2090. X * is identical to the mailing list (they
  2091. X * both carry the same set of messages). We prefer that you read the
  2092. X * messages through that newsgroup, to subscribing to the mailing list.
  2093. X * (If you can read that newsgroup, and are already on the mailing list,
  2094. X * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  2095. X * removed from the mailing list.)
  2096. X *
  2097. X * The address for mailing to list members is
  2098. X *       info-gnuplot@dartmouth.edu
  2099. X * and for mailing administrative requests is 
  2100. X *       info-gnuplot-request@dartmouth.edu
  2101. X * The mailing list for bug reports is 
  2102. X *       bug-gnuplot@dartmouth.edu
  2103. X * The list of those interested in beta-test versions is
  2104. X *       info-gnuplot-beta@dartmouth.edu
  2105. X */
  2106. X
  2107. X#include <math.h>
  2108. X#include <stdio.h>
  2109. X#include "plot.h"
  2110. X
  2111. X#ifdef vms
  2112. X#include <errno.h>
  2113. X#else
  2114. Xextern int errno;
  2115. X#endif /* vms */
  2116. X
  2117. X
  2118. Xextern struct value stack[STACK_DEPTH];
  2119. Xextern int s_p;
  2120. Xextern double zero;
  2121. X
  2122. Xstruct value *pop(), *Gcomplex(), *Ginteger();
  2123. X
  2124. Xdouble magnitude(), angle(), real(), imag();
  2125. X
  2126. X#define ITMAX   100
  2127. X#ifdef FLT_EPSILON
  2128. X#define MACHEPS FLT_EPSILON /* 1.0E-08 */
  2129. X#else
  2130. X#define MACHEPS 1.0E-08
  2131. X#endif
  2132. X#ifdef FLT_MIN_EXP
  2133. X#define MINEXP  FLT_MIN_EXP /* -88.0 */
  2134. X#else
  2135. X#define MINEXP  -88.0
  2136. X#endif
  2137. X#ifdef FLT_MAX
  2138. X#define OFLOW   FLT_MAX /* 1.0E+37 */
  2139. X#else
  2140. X#define OFLOW   1.0E+37
  2141. X#endif
  2142. X#ifdef FLT_MAX_10_EXP
  2143. X#define XBIG    FLT_MAX_10_EXP /* 2.55E+305 */
  2144. X#else
  2145. X#define XBIG    2.55E+305
  2146. X#endif
  2147. X
  2148. X/*
  2149. X * Mathematical constants
  2150. X */
  2151. X#define LNPI 1.14472988584940016
  2152. X#define LNSQRT2PI 0.9189385332046727
  2153. X#define PI 3.14159265358979323846
  2154. X#define PNT68 0.6796875
  2155. X#define SQRTPI 0.9189385332046727417803297
  2156. X#define SQRT_TWO 1.41421356237309504880168872420969809   /* JG */
  2157. X
  2158. X#ifndef min /* GCC ST uses inline functions */
  2159. X#define min(a,b) ((a) < (b) ? (a) : (b))
  2160. X#endif
  2161. X
  2162. X/* Global variables, not visible outside this file */
  2163. X#ifndef GAMMA
  2164. Xstatic int signgam = 0;
  2165. X#else
  2166. Xextern int signgam;
  2167. X#endif
  2168. Xstatic long     Xm1 = 2147483563L;
  2169. Xstatic long     Xm2 = 2147483399L;
  2170. Xstatic long     Xa1 = 40014L;
  2171. Xstatic long     Xa2 = 40692L;
  2172. X
  2173. X/* Local function declarations, not visible outside this file */
  2174. Xstatic double confrac();
  2175. Xstatic double ibeta();
  2176. Xstatic double igamma();
  2177. Xstatic double ranf();
  2178. X
  2179. X#ifndef GAMMA
  2180. X/* Provide GAMMA function for those who do not already have one */
  2181. Xstatic double lngamma();
  2182. Xstatic double lgamneg();
  2183. Xstatic double lgampos();
  2184. X
  2185. X/**
  2186. X * from statlib, Thu Jan 23 15:02:27 EST 1992 ***
  2187. X *
  2188. X * This file contains two algorithms for the logarithm of the gamma function.
  2189. X * Algorithm AS 245 is the faster (but longer) and gives an accuracy of about
  2190. X * 10-12 significant decimal digits except for small regions around X = 1 and
  2191. X * X = 2, where the function goes to zero.
  2192. X * The second algorithm is not part of the AS algorithms.   It is slower but
  2193. X * gives 14 or more significant decimal digits accuracy, except around X = 1
  2194. X * and X = 2.   The Lanczos series from which this algorithm is derived is
  2195. X * interesting in that it is a convergent series approximation for the gamma
  2196. X * function, whereas the familiar series due to De Moivre (and usually wrongly
  2197. X * called Stirling's approximation) is only an asymptotic approximation, as
  2198. X * is the true and preferable approximation due to Stirling.
  2199. X * 
  2200. X * Uses Lanczos-type approximation to ln(gamma) for z > 0. Reference: Lanczos,
  2201. X * C. 'A precision approximation of the gamma function', J. SIAM Numer.
  2202. X * Anal., B, 1, 86-96, 1964. Accuracy: About 14 significant digits except for
  2203. X * small regions in the vicinity of 1 and 2.
  2204. X * 
  2205. X * Programmer: Alan Miller CSIRO Division of Mathematics & Statistics
  2206. X * 
  2207. X * Latest revision - 17 April 1988
  2208. X * 
  2209. X * Additions: Translated from fortran to C, code added to handle values z < 0.
  2210. X * The global variable signgam contains the sign of the gamma function.
  2211. X * 
  2212. X * IMPORTANT: The signgam variable contains garbage until AFTER the call to
  2213. X * lngamma().
  2214. X * 
  2215. X * Permission granted to distribute freely for non-commercial purposes only
  2216. X * Copyright (c) 1992 Jos van der Woude, jvdwoude@hut.nl
  2217. X */
  2218. X
  2219. X/* Local data, not visible outside this file 
  2220. Xstatic double   a[] =
  2221. X{
  2222. X    0.9999999999995183E+00,
  2223. X    0.6765203681218835E+03,
  2224. X    -.1259139216722289E+04,
  2225. X    0.7713234287757674E+03,
  2226. X    -.1766150291498386E+03,
  2227. X    0.1250734324009056E+02,
  2228. X    -.1385710331296526E+00,
  2229. X    0.9934937113930748E-05,
  2230. X    0.1659470187408462E-06,
  2231. X};   */
  2232. X
  2233. X/* from Ray Toy */
  2234. Xstatic double a[] = {
  2235. X        .99999999999980993227684700473478296744476168282198,
  2236. X     676.52036812188509856700919044401903816411251975244084,
  2237. X   -1259.13921672240287047156078755282840836424300664868028,
  2238. X     771.32342877765307884865282588943070775227268469602500,
  2239. X    -176.61502916214059906584551353999392943274507608117860,
  2240. X      12.50734327868690481445893685327104972970563021816420,
  2241. X       -.13857109526572011689554706984971501358032683492780,
  2242. X        .00000998436957801957085956266828104544089848531228,
  2243. X        .00000015056327351493115583383579667028994545044040,
  2244. X};
  2245. X
  2246. Xstatic double   lgamneg(z)
  2247. Xdouble z;
  2248. X{
  2249. X    double          tmp;
  2250. X
  2251. X    /* Use reflection formula, then call lgampos() */
  2252. X    tmp = sin(z * PI);
  2253. X
  2254. X    if (fabs(tmp) < MACHEPS) {
  2255. X    tmp = 0.0;
  2256. X    } else if (tmp < 0.0) {
  2257. X    tmp = -tmp;
  2258. X        signgam = -1;
  2259. X    }
  2260. X    return LNPI - lgampos(1.0 - z) - log(tmp);
  2261. X
  2262. X}
  2263. X
  2264. Xstatic double   lgampos(z)
  2265. Xdouble z;
  2266. X{
  2267. X    double          sum;
  2268. X    double          tmp;
  2269. X    int             i;
  2270. X
  2271. X    sum = a[0];
  2272. X    for (i = 1, tmp = z; i < 9; i++) {
  2273. X        sum += a[i] / tmp;
  2274. X    tmp++;
  2275. X    }
  2276. X
  2277. X    return log(sum) + LNSQRT2PI - z - 6.5 + (z - 0.5) * log(z + 6.5);
  2278. X}
  2279. X
  2280. Xstatic double lngamma(z)
  2281. Xdouble z;
  2282. X{
  2283. X    signgam = 1.0;
  2284. X
  2285. X    if (z <= 0.0)
  2286. X    return lgamneg(z);
  2287. X    else
  2288. X    return lgampos(z);
  2289. X}
  2290. X
  2291. X#define GAMMA lngamma
  2292. X#endif /* GAMMA */
  2293. X
  2294. Xf_erf()
  2295. X{
  2296. Xstruct value a;
  2297. Xdouble x;
  2298. X
  2299. X        x = real(pop(&a));
  2300. X#ifndef ERF
  2301. X        x = x < 0.0 ? -igamma(0.5, x * x) : igamma(0.5, x * x);
  2302. X#else
  2303. X        x = erf(x);
  2304. X#endif
  2305. X        push( Gcomplex(&a,x,0.0) );
  2306. X}
  2307. X
  2308. Xf_erfc()
  2309. X{
  2310. Xstruct value a;
  2311. Xdouble x;
  2312. X
  2313. X        x = real(pop(&a));
  2314. X#ifndef ERF
  2315. X        x = x < 0.0 ? 1.0 + igamma(0.5, x * x) : 1.0 - igamma(0.5, x * x);
  2316. X#else
  2317. X        x = erfc(x);
  2318. X#endif
  2319. X        push( Gcomplex(&a,x,0.0) );
  2320. X}
  2321. X
  2322. Xf_ibeta()
  2323. X{
  2324. Xstruct value a;
  2325. Xdouble x;
  2326. Xdouble arg1;
  2327. Xdouble arg2;
  2328. X
  2329. X    x = real(pop(&a));
  2330. X    arg2 = real(pop(&a));
  2331. X    arg1 = real(pop(&a));
  2332. X
  2333. X    x = ibeta(arg1, arg2, x);
  2334. X    if(x == -1.0) {
  2335. X        undefined = TRUE;
  2336. X        push( Ginteger(&a,0) );
  2337. X    } else
  2338. X        push( Gcomplex(&a,x,0.0) );
  2339. X}
  2340. X
  2341. Xf_igamma()
  2342. X{
  2343. Xstruct value a;
  2344. Xdouble x;
  2345. Xdouble arg1;
  2346. X
  2347. X    x = real(pop(&a));
  2348. X    arg1 = real(pop(&a));
  2349. X
  2350. X    x = igamma(arg1,x);
  2351. X    if(x == -1.0) {
  2352. X        undefined = TRUE;
  2353. X        push( Ginteger(&a,0) );
  2354. X    } else
  2355. X        push( Gcomplex(&a,x,0.0) );
  2356. X}
  2357. X
  2358. Xf_gamma()
  2359. X{
  2360. Xregister double y;
  2361. Xstruct value a;
  2362. X
  2363. X        y = GAMMA(real(pop(&a)));
  2364. X    if (y > 88.0) {
  2365. X        undefined = TRUE;
  2366. X        push( Ginteger(&a,0) );
  2367. X    }
  2368. X    else
  2369. X        push( Gcomplex(&a,signgam * exp(y),0.0) );
  2370. X}
  2371. X
  2372. Xf_lgamma()
  2373. X{
  2374. Xstruct value a;
  2375. X
  2376. X        push( Gcomplex(&a, GAMMA(real(pop(&a))),0.0) );
  2377. X}
  2378. X
  2379. X#ifndef BADRAND
  2380. X
  2381. Xf_rand()
  2382. X{
  2383. Xstruct value a;
  2384. X
  2385. X        push( Gcomplex(&a, ranf(real(pop(&a))),0.0) );
  2386. X}
  2387. X
  2388. X#else
  2389. X
  2390. X/* Use only to observe the effect of a "bad" random number generator. */
  2391. Xf_rand()
  2392. X{
  2393. Xstruct value a;
  2394. X
  2395. Xstatic unsigned int y =0;
  2396. Xunsigned int maxran = 1000;
  2397. X
  2398. X    (void)real(pop(&a));
  2399. X    y = (781*y + 387) %maxran;
  2400. X
  2401. X    push( Gcomplex(&a, (double) y /maxran,0.0) );
  2402. X}
  2403. X
  2404. X#endif
  2405. X
  2406. X/** ibeta.c
  2407. X *
  2408. X *   DESCRIB   Approximate the incomplete beta function Ix(a, b).
  2409. X *
  2410. X *                           _
  2411. X *                          |(a + b)     /x  (a-1)         (b-1)
  2412. X *             Ix(a, b) = -_-------_--- * |  t     * (1 - t)     dt (a,b > 0)
  2413. X *                        |(a) * |(b)   /0
  2414. X *
  2415. X *
  2416. X *
  2417. X *   CALL      p = ibeta(a, b, x)
  2418. X *
  2419. X *             double    a    > 0
  2420. X *             double    b    > 0
  2421. X *             double    x    [0, 1]
  2422. X *
  2423. X *   WARNING   none
  2424. X *
  2425. X *   RETURN    double    p    [0, 1]
  2426. X *                            -1.0 on error condition
  2427. X *
  2428. X *   XREF      lngamma()
  2429. X *
  2430. X *   BUGS      none
  2431. X *
  2432. X *   REFERENCE The continued fraction expansion as given by
  2433. X *             Abramowitz and Stegun (1964) is used.
  2434. X *
  2435. X * Permission granted to distribute freely for non-commercial purposes only
  2436. X * Copyright (c) 1992 Jos van der Woude, jvdwoude@hut.nl
  2437. X */
  2438. X
  2439. Xstatic double          ibeta(a, b, x)
  2440. Xdouble a, b, x;
  2441. X{
  2442. X    /* Test for admissibility of arguments */
  2443. X    if (a <= 0.0 || b <= 0.0)
  2444. X    return -1.0;
  2445. X    if (x < 0.0 || x > 1.0)
  2446. X    return -1.0;;
  2447. X
  2448. X    /* If x equals 0 or 1, return x as prob */
  2449. X    if (x == 0.0 || x == 1.0)
  2450. X    return x;
  2451. X
  2452. X    /* Swap a, b if necessarry for more efficient evaluation */
  2453. X    return a < x * (a + b) ? 1.0 - confrac(b, a, 1.0 - x) : confrac(a, b, x);
  2454. X}
  2455. X
  2456. Xstatic double   confrac(a, b, x)
  2457. Xdouble a, b, x;
  2458. X{
  2459. X    double          Alo = 0.0;
  2460. X    double          Ahi;
  2461. X    double          Aev;
  2462. X    double          Aod;
  2463. X    double          Blo = 1.0;
  2464. X    double          Bhi = 1.0;
  2465. X    double          Bod = 1.0;
  2466. X    double          Bev = 1.0;
  2467. X    double          f;
  2468. X    double          fold;
  2469. X    double          Apb = a + b;
  2470. X    double          d;
  2471. X    int             i;
  2472. X    int             j;
  2473. X
  2474. X    /* Set up continued fraction expansion evaluation. */
  2475. X    Ahi = exp(GAMMA(Apb) + a * log(x) + b * log(1.0 - x) -
  2476. X              GAMMA(a + 1.0) - GAMMA(b));
  2477. X
  2478. X    /*
  2479. X     * Continued fraction loop begins here. Evaluation continues until
  2480. X     * maximum iterations are exceeded, or convergence achieved.
  2481. X     */
  2482. X    for (i = 0, j = 1, f = Ahi; i <= ITMAX; i++, j++) {
  2483. X    d = a + j + i;
  2484. X    Aev = -(a + i) * (Apb + i) * x / d / (d - 1.0);
  2485. X    Aod = j * (b - j) * x / d / (d + 1.0);
  2486. X    Alo = Bev * Ahi + Aev * Alo;
  2487. X    Blo = Bev * Bhi + Aev * Blo;
  2488. X    Ahi = Bod * Alo + Aod * Ahi;
  2489. X    Bhi = Bod * Blo + Aod * Bhi;
  2490. X
  2491. X    if (fabs(Bhi) < MACHEPS)
  2492. X        Bhi = 0.0;
  2493. X
  2494. X    if (Bhi != 0.0) {
  2495. X        fold = f;
  2496. X        f = Ahi / Bhi;
  2497. X        if (fabs(f - fold) < fabs(f) * MACHEPS)
  2498. X        return f;
  2499. X    }
  2500. X    }
  2501. X
  2502. X    return -1.0;
  2503. X}
  2504. X
  2505. X/** igamma.c
  2506. X *
  2507. X *   DESCRIB   Approximate the incomplete gamma function P(a, x).
  2508. X *
  2509. X *                         1     /x  -t   (a-1)
  2510. X *             P(a, x) = -_--- * |  e  * t     dt      (a > 0)
  2511. X *                       |(a)   /0
  2512. X *
  2513. X *   CALL      p = igamma(a, x)
  2514. X *
  2515. X *             double    a    >  0
  2516. X *             double    x    >= 0
  2517. X *
  2518. X *   WARNING   none
  2519. X *
  2520. X *   RETURN    double    p    [0, 1]
  2521. X *                            -1.0 on error condition
  2522. X *
  2523. X *   XREF      lngamma()
  2524. X *
  2525. X *   BUGS      Values 0 <= x <= 1 may lead to inaccurate results.
  2526. X *
  2527. X *   REFERENCE ALGORITHM AS239  APPL. STATIST. (1988) VOL. 37, NO. 3
  2528. X *
  2529. X * Permission granted to distribute freely for non-commercial purposes only
  2530. X * Copyright (c) 1992 Jos van der Woude, jvdwoude@hut.nl
  2531. X */
  2532. X
  2533. X/* Global variables, not visible outside this file */
  2534. Xstatic double   pn1, pn2, pn3, pn4, pn5, pn6;
  2535. X
  2536. Xstatic double          igamma(a, x)
  2537. Xdouble a, x;
  2538. X{
  2539. X    double          arg;
  2540. X    double          aa;
  2541. X    double          an;
  2542. X    double          b;
  2543. X    int             i;
  2544. X
  2545. X    /* Check that we have valid values for a and x */
  2546. X    if (x < 0.0 || a <= 0.0)
  2547. X    return -1.0;
  2548. X
  2549. X    /* Deal with special cases */
  2550. X    if (x == 0.0)
  2551. X    return 0.0;
  2552. X    if (x > XBIG)
  2553. X    return 1.0;
  2554. X
  2555. X    /* Check value of factor arg */
  2556. X    arg = a * log(x) - x - GAMMA(a + 1.0);
  2557. X    if (arg < MINEXP)
  2558. X    return -1.0;
  2559. X    arg = exp(arg);
  2560. X
  2561. X    /* Choose infinite series or continued fraction. */
  2562. X
  2563. X    if ((x > 1.0) && (x >= a + 2.0)) {
  2564. X    /* Use a continued fraction expansion */
  2565. X
  2566. X    double          rn;
  2567. X    double          rnold;
  2568. X
  2569. X    aa = 1.0 - a;
  2570. X    b = aa + x + 1.0;
  2571. X    pn1 = 1.0;
  2572. X    pn2 = x;
  2573. X    pn3 = x + 1.0;
  2574. X    pn4 = x * b;
  2575. X    rnold = pn3 / pn4;
  2576. X
  2577. X    for (i = 1; i <= ITMAX; i++) {
  2578. X
  2579. X        aa++;
  2580. X        b += 2.0;
  2581. X        an = aa * (double) i;
  2582. X
  2583. X        pn5 = b * pn3 - an * pn1;
  2584. X        pn6 = b * pn4 - an * pn2;
  2585. X
  2586. X        if (pn6 != 0.0) {
  2587. X
  2588. X        rn = pn5 / pn6;
  2589. X        if (fabs(rnold - rn) <= min(MACHEPS, MACHEPS * rn))
  2590. X            return 1.0 - arg * rn * a;
  2591. X
  2592. X        rnold = rn;
  2593. X        }
  2594. X        pn1 = pn3;
  2595. X        pn2 = pn4;
  2596. X        pn3 = pn5;
  2597. X        pn4 = pn6;
  2598. X
  2599. X        /* Re-scale terms in continued fraction if terms are large */
  2600. X        if (fabs(pn5) >= OFLOW) {
  2601. X
  2602. X        pn1 /= OFLOW;
  2603. X        pn2 /= OFLOW;
  2604. X        pn3 /= OFLOW;
  2605. X        pn4 /= OFLOW;
  2606. X        }
  2607. X    }
  2608. X    } else {
  2609. X    /* Use Pearson's series expansion. */
  2610. X
  2611. X    for (i = 0, aa = a, an = b = 1.0; i <= ITMAX; i++) {
  2612. X
  2613. X        aa++;
  2614. X        an *= x / aa;
  2615. X        b += an;
  2616. X        if (an < b * MACHEPS)
  2617. X        return arg * b;
  2618. X    }
  2619. X    }
  2620. X    return -1.0;
  2621. X}
  2622. X
  2623. X/***********************************************************************
  2624. X     double ranf(double init)
  2625. X                RANDom number generator as a Function
  2626. X     Returns a random floating point number from a uniform distribution
  2627. X     over 0 - 1 (endpoints of this interval are not returned) using a
  2628. X     large integer generator.
  2629. X     This is a transcription from Pascal to Fortran of routine
  2630. X     Uniform_01 from the paper
  2631. X     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
  2632. X     with Splitting Facilities." ACM Transactions on Mathematical
  2633. X     Software, 17:98-111 (1991)
  2634. X
  2635. X               GeNerate LarGe Integer
  2636. X     Returns a random integer following a uniform distribution over
  2637. X     (1, 2147483562) using the generator.
  2638. X     This is a transcription from Pascal to Fortran of routine
  2639. X     Random from the paper
  2640. X     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
  2641. X     with Splitting Facilities." ACM Transactions on Mathematical
  2642. X     Software, 17:98-111 (1991)
  2643. X***********************************************************************/
  2644. Xstatic double          ranf(init)
  2645. Xdouble init;
  2646. X{
  2647. X
  2648. X    long            k, z;
  2649. X    static int      firsttime = 1;
  2650. X    static long     s1, s2;
  2651. X
  2652. X    /* (Re)-Initialize seeds if necessary */
  2653. X    if (init < 0.0 || firsttime == 1) {
  2654. X    firsttime = 0;
  2655. X    s1 = 1234567890L;
  2656. X    s2 = 1234567890L;
  2657. X    }
  2658. X    /* Generate pseudo random integers */
  2659. X    k = s1 / 53668L;
  2660. X    s1 = Xa1 * (s1 - k * 53668L) - k * 12211;
  2661. X    if (s1 < 0)
  2662. X    s1 += Xm1;
  2663. X    k = s2 / 52774L;
  2664. X    s2 = Xa2 * (s2 - k * 52774L) - k * 3791;
  2665. X    if (s2 < 0)
  2666. X    s2 += Xm2;
  2667. X    z = s1 - s2;
  2668. X    if (z < 1)
  2669. X    z += (Xm1 - 1);
  2670. X
  2671. X    /*
  2672. X     * 4.656613057E-10 is 1/Xm1.  Xm1 is set at the top of this file and is
  2673. X     * currently 2147483563. If Xm1 changes, change this also.
  2674. X     */
  2675. X    return (double) 4.656613057E-10 *z;
  2676. X}
  2677. X
  2678. X/* ----------------------------------------------------------------
  2679. X   Following to specfun.c made by John Grosh (jgrosh@arl.mil)
  2680. X   on 28 OCT 1992.
  2681. X   ---------------------------------------------------------------- */
  2682. X
  2683. Xf_normal()    /* Normal or Gaussian Probability Function */
  2684. X{
  2685. Xstruct value a;
  2686. Xdouble x;
  2687. X
  2688. X    /* ref. Abramowitz and Stegun 1964, "Handbook of Mathematical 
  2689. X       Functions", Applied Mathematics Series, vol 55,
  2690. X       Chapter 26, page 934, Eqn. 26.2.29 and Jos van der Woude 
  2691. X           code found above */
  2692. X
  2693. X    x = real(pop(&a));
  2694. X
  2695. X#ifndef ERF
  2696. X        x = 0.5 * SQRT_TWO * x;
  2697. X        x = 0.5 * (1.0 + (x < 0.0 ? -igamma(0.5, x * x) : igamma(0.5, x * x)));
  2698. X#else
  2699. X    x = 0.5 * (1.0 + erf(0.5 * SQRT_TWO * x));
  2700. X#endif
  2701. X        push( Gcomplex(&a,x,0.0) );
  2702. X}
  2703. X
  2704. Xf_inverse_normal()  /* Inverse normal distribution function */
  2705. X{
  2706. Xstruct value a;
  2707. Xdouble x;
  2708. Xdouble inverse_normal_func();
  2709. X
  2710. X    x = real(pop(&a));
  2711. X
  2712. X    if (fabs(x) >= 1.0) {
  2713. X        undefined = TRUE;
  2714. X        push(Gcomplex(&a,0.0, 0.0));
  2715. X    } else {
  2716. X        push( Gcomplex(&a,inverse_normal_func(x), 0.0) );
  2717. X    }
  2718. X}
  2719. X
  2720. X
  2721. Xf_inverse_erf()  /* Inverse error function */
  2722. X{
  2723. Xstruct value a;
  2724. Xdouble x;
  2725. Xdouble inverse_error_func();
  2726. X
  2727. X    x = real(pop(&a));
  2728. X
  2729. X    if (fabs(x) >= 1.0) {
  2730. X        undefined = TRUE;
  2731. X        push(Gcomplex(&a,0.0, 0.0));
  2732. X    } else {
  2733. X        push( Gcomplex(&a,inverse_error_func(x), 0.0) );
  2734. X    }
  2735. X}
  2736. X
  2737. Xdouble 
  2738. Xinverse_normal_func(p)
  2739. Xdouble p;
  2740. X{
  2741. X    /* 
  2742. X           Source: This routine was derived (using f2c) from the 
  2743. X                   FORTRAN subroutine MDNRIS found in 
  2744. X                   ACM Algorithm 602 obtained from netlib.
  2745. X
  2746. X                   MDNRIS code contains the 1978 Copyright 
  2747. X                   by IMSL, INC. .  Since MDNRIS has been 
  2748. X                   submitted to netlib it may be used with 
  2749. X                   the restriction that it may only be 
  2750. X                   used for noncommercial purposes and that
  2751. X                   IMSL be acknowledged as the copyright-holder
  2752. X                   of the code.
  2753. X        */
  2754. X
  2755. X    /* Initialized data */
  2756. X    static double eps = 1e-10;
  2757. X    static double g0 = 1.851159e-4;
  2758. X    static double g1 = -.002028152;
  2759. X    static double g2 = -.1498384;
  2760. X    static double g3 = .01078639;
  2761. X    static double h0 = .09952975;
  2762. X    static double h1 = .5211733;
  2763. X    static double h2 = -.06888301;
  2764. X    static double sqrt2 = 1.414213562373095;
  2765. X
  2766. X    /* Local variables */
  2767. X    static double a, w, x;
  2768. X    static double sd, wi, sn, y;
  2769. X
  2770. X    double inverse_error_func();
  2771. X
  2772. X    /* Note: 0.0 < p < 1.0 */
  2773. X
  2774. X    /* p too small, compute y directly */
  2775. X    if (p <= eps) {
  2776. X        a = p + p;
  2777. X        w = sqrt(-(double)log(a + (a - a * a)));
  2778. X
  2779. X        /* use a rational function in 1.0 / w */
  2780. X        wi = 1.0 / w;
  2781. X        sn = ((g3 * wi + g2) * wi + g1) * wi;
  2782. X        sd = ((wi + h2) * wi + h1) * wi + h0;
  2783. X        y = w + w * (g0 + sn / sd);
  2784. X        y = -y * sqrt2;
  2785. X    } else {
  2786. X        x = 1.0 - (p + p);
  2787. X        y = inverse_error_func(x);
  2788. X        y = -sqrt2 * y;
  2789. X    }
  2790. X    return(y);
  2791. X} 
  2792. X
  2793. X
  2794. Xdouble 
  2795. Xinverse_error_func(p) 
  2796. Xdouble p;
  2797. X{
  2798. X    /* 
  2799. X           Source: This routine was derived (using f2c) from the 
  2800. X                   FORTRAN subroutine MERFI found in 
  2801. X                   ACM Algorithm 602 obtained from netlib.
  2802. X
  2803. X                   MDNRIS code contains the 1978 Copyright 
  2804. X                   by IMSL, INC. .  Since MERFI has been 
  2805. X                   submitted to netlib, it may be used with 
  2806. X                   the restriction that it may only be 
  2807. X                   used for noncommercial purposes and that
  2808. X                   IMSL be acknowledged as the copyright-holder
  2809. X                   of the code.
  2810. X        */
  2811. X
  2812. X
  2813. X
  2814. X    /* Initialized data */
  2815. X    static double a1 = -.5751703;
  2816. X    static double a2 = -1.896513;
  2817. X    static double a3 = -.05496261;
  2818. X    static double b0 = -.113773;
  2819. X    static double b1 = -3.293474;
  2820. X    static double b2 = -2.374996;
  2821. X    static double b3 = -1.187515;
  2822. X    static double c0 = -.1146666;
  2823. X    static double c1 = -.1314774;
  2824. X    static double c2 = -.2368201;
  2825. X    static double c3 = .05073975;
  2826. X    static double d0 = -44.27977;
  2827. X    static double d1 = 21.98546;
  2828. X    static double d2 = -7.586103;
  2829. X    static double e0 = -.05668422;
  2830. X    static double e1 = .3937021;
  2831. X    static double e2 = -.3166501;
  2832. X    static double e3 = .06208963;
  2833. X    static double f0 = -6.266786;
  2834. X    static double f1 = 4.666263;
  2835. X    static double f2 = -2.962883;
  2836. X    static double g0 = 1.851159e-4;
  2837. X    static double g1 = -.002028152;
  2838. X    static double g2 = -.1498384;
  2839. X    static double g3 = .01078639;
  2840. X    static double h0 = .09952975;
  2841. X    static double h1 = .5211733;
  2842. X    static double h2 = -.06888301;
  2843. X
  2844. X    /* Local variables */
  2845. X    static double a, b, f, w, x, y, z, sigma, z2, sd, wi, sn;
  2846. X
  2847. X    x = p;
  2848. X
  2849. X    /* determine sign of x */
  2850. X    if (x > 0)
  2851. X        sigma = 1.0;
  2852. X    else
  2853. X        sigma = -1.0;
  2854. X
  2855. X    /* Note: -1.0 < x < 1.0 */
  2856. X
  2857. X    z = fabs(x);
  2858. X
  2859. X    /* z between 0.0 and 0.85, approx. f by a 
  2860. X       rational function in z  */
  2861. X
  2862. X    if (z <= 0.85) {
  2863. X        z2 = z * z;
  2864. X        f = z + z * (b0 + a1 * z2 / (b1 + z2 + a2 
  2865. X            / (b2 + z2 + a3 / (b3 + z2))));
  2866. X
  2867. X    /* z greater than 0.85 */
  2868. X    } else {
  2869. X        a = 1.0 - z;
  2870. X        b = z;
  2871. X
  2872. X        /* reduced argument is in (0.85,1.0), 
  2873. X           obtain the transformed variable */
  2874. X
  2875. X        w = sqrt(-(double)log(a + a * b));
  2876. X
  2877. X        /* w greater than 4.0, approx. f by a 
  2878. X           rational function in 1.0 / w */
  2879. X
  2880. X        if (w >= 4.0) {
  2881. X            wi = 1.0 / w;
  2882. X            sn = ((g3 * wi + g2) * wi + g1) * wi;
  2883. X            sd = ((wi + h2) * wi + h1) * wi + h0;
  2884. X            f = w + w * (g0 + sn / sd);
  2885. X
  2886. X        /* w between 2.5 and 4.0, approx. 
  2887. X           f by a rational function in w */
  2888. X
  2889. X        } else if (w < 4.0 && w > 2.5) {
  2890. X            sn = ((e3 * w + e2) * w + e1) * w;
  2891. X            sd = ((w + f2) * w + f1) * w + f0;
  2892. X            f = w + w * (e0 + sn / sd);
  2893. X
  2894. X        /* w between 1.13222 and 2.5, approx. f by 
  2895. X           a rational function in w */
  2896. X        } else if (w <= 2.5 && w > 1.13222) {
  2897. X            sn = ((c3 * w + c2) * w + c1) * w;
  2898. X            sd = ((w + d2) * w + d1) * w + d0;
  2899. X            f = w + w * (c0 + sn / sd);
  2900. X        }
  2901. X    }
  2902. X    y = sigma * f;
  2903. X    return(y);
  2904. X}
  2905. X
  2906. END_OF_FILE
  2907.   if test 20743 -ne `wc -c <'gnuplot/specfun.c'`; then
  2908.     echo shar: \"'gnuplot/specfun.c'\" unpacked with wrong size!
  2909.   fi
  2910.   # end of 'gnuplot/specfun.c'
  2911. fi
  2912. echo shar: End of archive 17 \(of 33\).
  2913. cp /dev/null ark17isdone
  2914. MISSING=""
  2915. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ; do
  2916.     if test ! -f ark${I}isdone ; then
  2917.     MISSING="${MISSING} ${I}"
  2918.     fi
  2919. done
  2920. if test "${MISSING}" = "" ; then
  2921.     echo You have unpacked all 33 archives.
  2922.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2923. else
  2924.     echo You still must unpack the following archives:
  2925.     echo "        " ${MISSING}
  2926. fi
  2927. exit 0
  2928. exit 0 # Just in case...
  2929.