home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume11 / gnuplot2 / part07 < prev    next >
Encoding:
Text File  |  1990-03-25  |  48.4 KB  |  2,157 lines

  1. Newsgroups: comp.sources.misc
  2. organization: Pixar -- Marin County, California
  3. subject: v11i072: Gnuplot 2.0 - 7 of 14
  4. From: thaw@ucbvax.Berkeley.EDU@pixar.UUCP (Tom Williams)
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 11, Issue 72
  8. Submitted-by: thaw@ucbvax.Berkeley.EDU@pixar.UUCP (Tom Williams)
  9. Archive-name: gnuplot2/part07
  10.  
  11. This is gnuplot.sh07
  12.  
  13. --- CUT HERE ---
  14. #! /bin/sh
  15. echo x - misc.c
  16. sed 's/^X//' >misc.c <<'*-*-END-of-misc.c-*-*'
  17. X/* GNUPLOT - misc.c */
  18. X/*
  19. X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  20. X *
  21. X * Permission to use, copy, and distribute this software and its
  22. X * documentation for any purpose with or without fee is hereby granted, 
  23. X * provided that the above copyright notice appear in all copies and 
  24. X * that both that copyright notice and this permission notice appear 
  25. X * in supporting documentation.
  26. X *
  27. X * Permission to modify the software is granted, but not the right to
  28. X * distribute the modified code.  Modifications are to be distributed 
  29. X * as patches to released version.
  30. X *  
  31. X * This software  is provided "as is" without express or implied warranty.
  32. X * 
  33. X *
  34. X * AUTHORS
  35. X * 
  36. X *   Original Software:
  37. X *     Thomas Williams,  Colin Kelley.
  38. X * 
  39. X *   Gnuplot 2.0 additions:
  40. X *       Russell Lang, Dave Kotz, John Campbell.
  41. X * 
  42. X * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  43. X * 
  44. X */
  45. X
  46. X#include <stdio.h>
  47. X#include <math.h>
  48. X#include "plot.h"
  49. X#include "setshow.h"
  50. X#include "help.h"
  51. X#ifdef __TURBOC__
  52. X#include <graphics.h>
  53. X#endif
  54. X
  55. Xextern int c_token;
  56. Xextern char replot_line[];
  57. Xextern struct at_type at;
  58. Xextern struct ft_entry ft[];
  59. Xextern struct udft_entry *first_udf;
  60. Xextern struct udvt_entry *first_udv;
  61. X
  62. Xextern struct at_type *temp_at();
  63. X
  64. Xextern BOOLEAN interactive;
  65. Xextern char *infile_name;
  66. Xextern int inline_num;
  67. X
  68. X/* State information for load_file(), to recover from errors
  69. X * and properly handle recursive load_file calls
  70. X */
  71. Xtypedef struct lf_state_struct LFS;
  72. Xstruct lf_state_struct {
  73. X    FILE *fp;                /* file pointer for load file */
  74. X    char *name;            /* name of file */
  75. X    BOOLEAN interactive;        /* value of interactive flag on entry */
  76. X    int inline_num;            /* inline_num on entry */
  77. X    LFS *prev;                /* defines a stack */
  78. X} *lf_head = NULL;            /* NULL if not in load_file */
  79. X
  80. Xstatic BOOLEAN lf_pop();
  81. Xstatic void lf_push();
  82. X
  83. X/*
  84. X * instead of <strings.h>
  85. X */
  86. Xextern int strcmp();
  87. X
  88. X
  89. X/*
  90. X * cp_free() releases any memory which was previously malloc()'d to hold
  91. X *   curve points.
  92. X */
  93. Xcp_free(cp)
  94. Xstruct curve_points *cp;
  95. X{
  96. X    if (cp) {
  97. X        cp_free(cp->next_cp);
  98. X        if (cp->title)
  99. X            free((char *)cp->title);
  100. X        free((char *)cp);
  101. X    }
  102. X}
  103. X
  104. X
  105. X
  106. Xsave_functions(fp)
  107. XFILE *fp;
  108. X{
  109. Xregister struct udft_entry *udf = first_udf;
  110. X    
  111. X    if (fp) {
  112. X        while (udf) {
  113. X            if (udf->definition)
  114. X                fprintf(fp,"%s\n",udf->definition);
  115. X            udf = udf->next_udf;
  116. X        }
  117. X        (void) fclose(fp);
  118. X    } else
  119. X        os_error("Cannot open save file",c_token);            
  120. X}
  121. X
  122. X
  123. Xsave_variables(fp)
  124. XFILE *fp;
  125. X{
  126. Xregister struct udvt_entry *udv = first_udv->next_udv;    /* skip pi */
  127. X
  128. X    if (fp) {
  129. X        while (udv) {
  130. X            if (!udv->udv_undef) {
  131. X                fprintf(fp,"%s = ",udv->udv_name);
  132. X                disp_value(fp,&(udv->udv_value));
  133. X                (void) putc('\n',fp);
  134. X            }
  135. X            udv = udv->next_udv;
  136. X        }
  137. X        (void) fclose(fp);
  138. X    } else
  139. X        os_error("Cannot open save file",c_token);            
  140. X}
  141. X
  142. X
  143. Xsave_all(fp)
  144. XFILE *fp;
  145. X{
  146. Xregister struct udft_entry *udf = first_udf;
  147. Xregister struct udvt_entry *udv = first_udv->next_udv;    /* skip pi */
  148. X
  149. X    if (fp) {
  150. X        save_set_all(fp);
  151. X        while (udf) {
  152. X            if (udf->definition)
  153. X                fprintf(fp,"%s\n",udf->definition);
  154. X            udf = udf->next_udf;
  155. X        }
  156. X        while (udv) {
  157. X            if (!udv->udv_undef) {
  158. X                fprintf(fp,"%s = ",udv->udv_name);
  159. X                disp_value(fp,&(udv->udv_value));
  160. X                (void) putc('\n',fp);
  161. X            }
  162. X            udv = udv->next_udv;
  163. X        }
  164. X        fprintf(fp,"%s\n",replot_line);
  165. X        (void) fclose(fp);
  166. X    } else
  167. X        os_error("Cannot open save file",c_token);            
  168. X}
  169. X
  170. X
  171. Xsave_set(fp)
  172. XFILE *fp;
  173. X{
  174. X    if (fp) {
  175. X        save_set_all(fp);
  176. X        (void) fclose(fp);
  177. X    } else
  178. X        os_error("Cannot open save file",c_token);            
  179. X}
  180. X
  181. X
  182. Xsave_set_all(fp)
  183. XFILE *fp;
  184. X{
  185. Xstruct text_label *this_label;
  186. Xstruct arrow_def *this_arrow;
  187. X    fprintf(fp,"set terminal %s\n", term_tbl[term].name);
  188. X    fprintf(fp,"set output %s\n",strcmp(outstr,"STDOUT")? outstr : "" );
  189. X    fprintf(fp,"set %sclip points\n", (clip_points)? "" : "no");
  190. X    fprintf(fp,"set %sclip one\n", (clip_lines1)? "" : "no");
  191. X    fprintf(fp,"set %sclip two\n", (clip_lines2)? "" : "no");
  192. X    fprintf(fp,"set dummy %s\n",dummy_var);
  193. X    fprintf(fp,"set format x \"%s\"\n", xformat);
  194. X    fprintf(fp,"set format y \"%s\"\n", yformat);
  195. X    fprintf(fp,"set %sgrid\n", (grid)? "" : "no");
  196. X    switch (key) {
  197. X        case -1 : 
  198. X            fprintf(fp,"set key\n");
  199. X            break;
  200. X        case 0 :
  201. X            fprintf(fp,"set nokey\n");
  202. X            break;
  203. X        case 1 :
  204. X            fprintf(fp,"set key %g,%g\n",key_x,key_y);
  205. X            break;
  206. X    }
  207. X    fprintf(fp,"set nolabel\n");
  208. X    for (this_label = first_label; this_label != NULL;
  209. X            this_label = this_label->next) {
  210. X        fprintf(fp,"set label %d \"%s\" at %g,%g ",
  211. X               this_label->tag,
  212. X               this_label->text, this_label->x, this_label->y);
  213. X        switch(this_label->pos) {
  214. X            case LEFT : 
  215. X                fprintf(fp,"left");
  216. X                break;
  217. X            case CENTRE :
  218. X                fprintf(fp,"centre");
  219. X                break;
  220. X            case RIGHT :
  221. X                fprintf(fp,"right");
  222. X                break;
  223. X        }
  224. X        fputc('\n',fp);
  225. X    }
  226. X    fprintf(fp,"set noarrow\n");
  227. X    for (this_arrow = first_arrow; this_arrow != NULL;
  228. X            this_arrow = this_arrow->next) {
  229. X        fprintf(fp,"set arrow %d from %g,%g to %g,%g\n",
  230. X               this_arrow->tag,
  231. X               this_arrow->sx, this_arrow->sy,
  232. X               this_arrow->ex, this_arrow->ey);
  233. X    }
  234. X    if ((!log_x)||(!log_y))
  235. X        fprintf(fp,"set nologscale xy\n");
  236. X    if (log_x||log_y)
  237. X        fprintf(fp,"set logscale %c%c\n", 
  238. X            log_x ? 'x' : ' ', log_y ? 'y' : ' ');
  239. X    fprintf(fp,"set offsets %g, %g, %g, %g\n",loff,roff,toff,boff);
  240. X    fprintf(fp,"set %spolar\n", (polar)? "" : "no");
  241. X    fprintf(fp,"set samples %d\n",samples);
  242. X    fprintf(fp,"set size %g,%g\n",xsize,ysize);
  243. X    fprintf(fp,"set data style ");
  244. X    switch (data_style) {
  245. X        case LINES: fprintf(fp,"lines\n"); break;
  246. X        case POINTS: fprintf(fp,"points\n"); break;
  247. X        case IMPULSES: fprintf(fp,"impulses\n"); break;
  248. X        case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
  249. X        case DOTS: fprintf(fp,"dots\n"); break;
  250. X    }
  251. X    fprintf(fp,"set function style ");
  252. X    switch (func_style) {
  253. X        case LINES: fprintf(fp,"lines\n"); break;
  254. X        case POINTS: fprintf(fp,"points\n"); break;
  255. X        case IMPULSES: fprintf(fp,"impulses\n"); break;
  256. X        case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
  257. X        case DOTS: fprintf(fp,"dots\n"); break;
  258. X    }
  259. X    fprintf(fp,"set tics %s\n", (tic_in)? "in" : "out");
  260. X     save_tics(fp, xtics, 'x', &xticdef);
  261. X     save_tics(fp, ytics, 'y', &yticdef);
  262. X    fprintf(fp,"set title \"%s\"\n",title);
  263. X    fprintf(fp,"set xlabel \"%s\"\n",xlabel);
  264. X    fprintf(fp,"set xrange [%g : %g]\n",xmin,xmax);
  265. X    fprintf(fp,"set ylabel \"%s\"\n",ylabel);
  266. X    fprintf(fp,"set yrange [%g : %g]\n",ymin,ymax);
  267. X    fprintf(fp,"set %s %c%c\n", 
  268. X        (autoscale_y||autoscale_x) ? "autoscale" : "noautoscale", 
  269. X        autoscale_x ? 'x' : ' ', autoscale_y ? 'y' : ' ');
  270. X    fprintf(fp,"set zero %g\n",zero);
  271. X}
  272. X
  273. Xsave_tics(fp, onoff, axis, tdef)
  274. X    FILE *fp;
  275. X    BOOLEAN onoff;
  276. X    char axis;
  277. X    struct ticdef *tdef;
  278. X{
  279. X    if (onoff) {
  280. X       fprintf(fp,"set %ctics", axis);
  281. X       switch(tdef->type) {
  282. X          case TIC_COMPUTED: {
  283. X             break;
  284. X          }
  285. X          case TIC_SERIES: {
  286. X             fprintf(fp, " %g,%g,%g", tdef->def.series.start,
  287. X                    tdef->def.series.incr, tdef->def.series.end);
  288. X             break;
  289. X          }
  290. X          case TIC_USER: {
  291. X             register struct ticmark *t;
  292. X             fprintf(fp, " (");
  293. X             for (t = tdef->def.user; t != NULL; t=t->next) {
  294. X                if (t->label)
  295. X                  fprintf(fp, "\"%s\" ", t->label);
  296. X                if (t->next)
  297. X                  fprintf(fp, "%g, ", t->position);
  298. X                else
  299. X                  fprintf(fp, "%g", t->position);
  300. X             }
  301. X             fprintf(fp, ")");
  302. X             break;
  303. X          } 
  304. X       }
  305. X       fprintf(fp, "\n");
  306. X    } else {
  307. X       fprintf(fp,"set no%ctics\n", axis);
  308. X    }
  309. X}
  310. X
  311. Xload_file(fp, name)
  312. X    FILE *fp;
  313. X    char *name;
  314. X{
  315. X    register int len;
  316. X    extern char input_line[];
  317. X
  318. X    int start, left;
  319. X    int more;
  320. X    int stop = FALSE;
  321. X
  322. X    lf_push(fp);            /* save state for errors and recursion */
  323. X
  324. X    if (fp == (FILE *)NULL) {
  325. X       char errbuf[BUFSIZ];
  326. X       (void) sprintf(errbuf, "Cannot open load file '%s'", name);
  327. X       os_error(errbuf, c_token);
  328. X    } else {
  329. X       /* go into non-interactive mode during load */
  330. X       /* will be undone below, or in load_file_error */
  331. X       interactive = FALSE;
  332. X       inline_num = 0;
  333. X       infile_name = name;
  334. X
  335. X       while (!stop) {        /* read all commands in file */
  336. X          /* read one command */
  337. X          left = MAX_LINE_LEN;
  338. X          start = 0;
  339. X          more = TRUE;
  340. X
  341. X          while (more) {
  342. X             if (fgets(&(input_line[start]), left, fp) == NULL) {
  343. X                stop = TRUE; /* EOF in file */
  344. X                input_line[start] = '\0';
  345. X                more = FALSE;    
  346. X             } else {
  347. X                inline_num++;
  348. X                len = strlen(input_line) - 1;
  349. X                if (input_line[len] == '\n') { /* remove any newline */
  350. X                    input_line[len] = '\0';
  351. X                    /* Look, len was 1-1 = 0 before, take care here! */
  352. X                    if (len > 0) --len;
  353. X                } else if (len+1 >= left)
  354. X                  int_error("Input line too long",NO_CARET);
  355. X                 
  356. X                if (input_line[len] == '\\') { /* line continuation */
  357. X                    start = len;
  358. X                    left -= len;
  359. X                } else
  360. X                  more = FALSE;
  361. X             }
  362. X          }
  363. X
  364. X          if (strlen(input_line) > 0) {
  365. X             screen_ok = FALSE;    /* make sure command line is
  366. X                               echoed on error */
  367. X             do_line();
  368. X          }
  369. X       }
  370. X    }
  371. X
  372. X    /* pop state */
  373. X    (void) lf_pop();        /* also closes file fp */
  374. X}
  375. X
  376. X/* pop from load_file state stack */
  377. Xstatic BOOLEAN                /* FALSE if stack was empty */
  378. Xlf_pop()                    /* called by load_file and load_file_error */
  379. X{
  380. X    LFS *lf;
  381. X
  382. X    if (lf_head == NULL)
  383. X     return(FALSE);
  384. X    else {
  385. X       lf = lf_head;
  386. X       if (lf->fp != (FILE *)NULL)
  387. X        (void) fclose(lf->fp);
  388. X       interactive = lf->interactive;
  389. X       inline_num = lf->inline_num;
  390. X       infile_name = lf->name;
  391. X       lf_head = lf->prev;
  392. X       free((char *)lf);
  393. X       return(TRUE);
  394. X    }
  395. X}
  396. X
  397. X/* push onto load_file state stack */
  398. X/* essentially, we save information needed to undo the load_file changes */
  399. Xstatic void
  400. Xlf_push(fp)            /* called by load_file */
  401. X    FILE *fp;
  402. X{
  403. X    LFS *lf;
  404. X    
  405. X    lf = (LFS *)alloc(sizeof(LFS), (char *)NULL);
  406. X    if (lf == (LFS *)NULL) {
  407. X       if (fp != (FILE *)NULL)
  408. X        (void) fclose(fp);        /* it won't be otherwise */
  409. X       int_error("not enough memory to load file", c_token);
  410. X    }
  411. X     
  412. X    lf->fp = fp;            /* save this file pointer */
  413. X    lf->name = infile_name;    /* save current name */
  414. X    lf->interactive = interactive;    /* save current state */
  415. X    lf->inline_num = inline_num; /* save current line number */
  416. X    lf->prev = lf_head;        /* link to stack */
  417. X    lf_head = lf;
  418. X}
  419. X
  420. Xload_file_error()            /* called from main */
  421. X{
  422. X    /* clean up from error in load_file */
  423. X    /* pop off everything on stack */
  424. X    while(lf_pop())
  425. X     ;
  426. X}
  427. X
  428. X/* find char c in string str; return p such that str[p]==c;
  429. X * if c not in str then p=strlen(str)
  430. X */
  431. Xint
  432. Xinstring(str, c)
  433. X    char *str;
  434. X    char c;
  435. X{
  436. X    int pos = 0;
  437. X
  438. X    while (str != NULL && *str != '\0' && c != *str) {
  439. X       str++; 
  440. X       pos++;
  441. X    }
  442. X    return (pos);
  443. X}
  444. X
  445. Xshow_functions()
  446. X{
  447. Xregister struct udft_entry *udf = first_udf;
  448. X
  449. X    fprintf(stderr,"\n\tUser-Defined Functions:\n");
  450. X
  451. X    while (udf) {
  452. X        if (udf->definition)
  453. X            fprintf(stderr,"\t%s\n",udf->definition);
  454. X        else
  455. X            fprintf(stderr,"\t%s is undefined\n",udf->udf_name);
  456. X        udf = udf->next_udf;
  457. X    }
  458. X}
  459. X
  460. X
  461. Xshow_at()
  462. X{
  463. X    (void) putc('\n',stderr);
  464. X    disp_at(temp_at(),0);
  465. X}
  466. X
  467. X
  468. Xdisp_at(curr_at, level)
  469. Xstruct at_type *curr_at;
  470. Xint level;
  471. X{
  472. Xregister int i, j;
  473. Xregister union argument *arg;
  474. X
  475. X    for (i = 0; i < curr_at->a_count; i++) {
  476. X        (void) putc('\t',stderr);
  477. X        for (j = 0; j < level; j++)
  478. X            (void) putc(' ',stderr);    /* indent */
  479. X
  480. X            /* print name of instruction */
  481. X
  482. X        fputs(ft[(int)(curr_at->actions[i].index)].f_name,stderr);
  483. X        arg = &(curr_at->actions[i].arg);
  484. X
  485. X            /* now print optional argument */
  486. X
  487. X        switch(curr_at->actions[i].index) {
  488. X          case PUSH:    fprintf(stderr," %s\n", arg->udv_arg->udv_name);
  489. X                    break;
  490. X          case PUSHC:    (void) putc(' ',stderr);
  491. X                    disp_value(stderr,&(arg->v_arg));
  492. X                    (void) putc('\n',stderr);
  493. X                    break;
  494. X          case PUSHD:    fprintf(stderr," %s dummy\n",
  495. X                      arg->udf_arg->udf_name);
  496. X                    break;
  497. X          case CALL:    fprintf(stderr," %s", arg->udf_arg->udf_name);
  498. X                    if (arg->udf_arg->at) {
  499. X                        (void) putc('\n',stderr);
  500. X                        disp_at(arg->udf_arg->at,level+2); /* recurse! */
  501. X                    } else
  502. X                        fputs(" (undefined)\n",stderr);
  503. X                    break;
  504. X          case JUMP:
  505. X          case JUMPZ:
  506. X          case JUMPNZ:
  507. X          case JTERN:
  508. X                    fprintf(stderr," +%d\n",arg->j_arg);
  509. X                    break;
  510. X          default:
  511. X                    (void) putc('\n',stderr);
  512. X        }
  513. X    }
  514. X}
  515. X
  516. X
  517. X/* alloc:
  518. X * allocate memory 
  519. X * This is a protected version of malloc. It causes an int_error 
  520. X * if there is not enough memory, but first it tries FreeHelp() 
  521. X * to make some room, and tries again. If message is NULL, we 
  522. X * allow NULL return. Otherwise, we handle the error, using the
  523. X * message to create the int_error string.
  524. X */
  525. X
  526. Xchar *
  527. Xalloc(size, message)
  528. X    unsigned int size;                /* # of bytes */
  529. X    char *message;            /* description of what is being allocated */
  530. X{
  531. X    char *p;                /* the new allocation */
  532. X    char errbuf[100];        /* error message string */
  533. X    extern char *malloc();
  534. X
  535. X    p = malloc(size);
  536. X    if (p == (char *)NULL) {
  537. X#ifndef VMS
  538. X       FreeHelp();            /* out of memory, try to make some room */
  539. X#endif
  540. X       
  541. X       p = malloc(size);        /* try again */
  542. X       if (p == (char *)NULL) {
  543. X          /* really out of memory */
  544. X          if (message != NULL) {
  545. X             (void) sprintf(errbuf, "out of memory for %s", message);
  546. X             int_error(errbuf, NO_CARET);
  547. X             /* NOTREACHED */
  548. X          }
  549. X          /* else we return NULL */
  550. X       }
  551. X    }
  552. X
  553. X    return(p);
  554. X}
  555. *-*-END-of-misc.c-*-*
  556. echo x - eval.c
  557. sed 's/^X//' >eval.c <<'*-*-END-of-eval.c-*-*'
  558. X/* GNUPLOT - eval.c */
  559. X/*
  560. X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  561. X *
  562. X * Permission to use, copy, and distribute this software and its
  563. X * documentation for any purpose with or without fee is hereby granted, 
  564. X * provided that the above copyright notice appear in all copies and 
  565. X * that both that copyright notice and this permission notice appear 
  566. X * in supporting documentation.
  567. X *
  568. X * Permission to modify the software is granted, but not the right to
  569. X * distribute the modified code.  Modifications are to be distributed 
  570. X * as patches to released version.
  571. X *  
  572. X * This software  is provided "as is" without express or implied warranty.
  573. X * 
  574. X *
  575. X * AUTHORS
  576. X * 
  577. X *   Original Software:
  578. X *     Thomas Williams,  Colin Kelley.
  579. X * 
  580. X *   Gnuplot 2.0 additions:
  581. X *       Russell Lang, Dave Kotz, John Campbell.
  582. X * 
  583. X * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  584. X * 
  585. X */
  586. X
  587. X#include <stdio.h>
  588. X#include "plot.h"
  589. X
  590. Xextern int c_token;
  591. Xextern struct ft_entry ft[];
  592. Xextern struct udvt_entry *first_udv;
  593. Xextern struct udft_entry *first_udf;
  594. Xextern struct at_type at;
  595. Xextern struct lexical_unit token[];
  596. X
  597. Xstruct value *integer();
  598. X
  599. X
  600. X
  601. Xstruct udvt_entry *
  602. Xadd_udv(t_num)  /* find or add value and return pointer */
  603. Xint t_num;
  604. X{
  605. Xregister struct udvt_entry **udv_ptr = &first_udv;
  606. X
  607. X    /* check if it's already in the table... */
  608. X
  609. X    while (*udv_ptr) {
  610. X        if (equals(t_num,(*udv_ptr)->udv_name))
  611. X            return(*udv_ptr);
  612. X        udv_ptr = &((*udv_ptr)->next_udv);
  613. X    }
  614. X
  615. X    *udv_ptr = (struct udvt_entry *)
  616. X      alloc((unsigned int)sizeof(struct udvt_entry), "value");
  617. X    (*udv_ptr)->next_udv = NULL;
  618. X    copy_str((*udv_ptr)->udv_name,t_num);
  619. X    (*udv_ptr)->udv_value.type = INT;    /* not necessary, but safe! */
  620. X    (*udv_ptr)->udv_undef = TRUE;
  621. X    return(*udv_ptr);
  622. X}
  623. X
  624. X
  625. Xstruct udft_entry *
  626. Xadd_udf(t_num)  /* find or add function and return pointer */
  627. Xint t_num; /* index to token[] */
  628. X{
  629. Xregister struct udft_entry **udf_ptr = &first_udf;
  630. X
  631. X    while (*udf_ptr) {
  632. X        if (equals(t_num,(*udf_ptr)->udf_name))
  633. X            return(*udf_ptr);
  634. X        udf_ptr = &((*udf_ptr)->next_udf);
  635. X    }
  636. X     *udf_ptr = (struct udft_entry *)
  637. X      alloc((unsigned int)sizeof(struct udft_entry), "function");
  638. X    (*udf_ptr)->next_udf = (struct udft_entry *) NULL;
  639. X    (*udf_ptr)->definition = NULL;
  640. X    (*udf_ptr)->at = NULL;
  641. X    copy_str((*udf_ptr)->udf_name,t_num);
  642. X    (void) integer(&((*udf_ptr)->dummy_value), 0);
  643. X    return(*udf_ptr);
  644. X}
  645. X
  646. X
  647. Xunion argument *
  648. Xadd_action(sf_index)
  649. Xenum operators sf_index;        /* index of p-code function */
  650. X{
  651. X    if (at.a_count >= MAX_AT_LEN)
  652. X        int_error("action table overflow",NO_CARET);
  653. X    at.actions[at.a_count].index = sf_index;
  654. X    return(&(at.actions[at.a_count++].arg));
  655. X}
  656. X
  657. X
  658. Xint standard(t_num)  /* return standard function index or 0 */
  659. X{
  660. Xregister int i;
  661. X    for (i = (int)SF_START; ft[i].f_name != NULL; i++) {
  662. X        if (equals(t_num,ft[i].f_name))
  663. X            return(i);
  664. X    }
  665. X    return(0);
  666. X}
  667. X
  668. X
  669. Xexecute_at(at_ptr)
  670. Xstruct at_type *at_ptr;
  671. X{
  672. Xregister int i,index,count,offset;
  673. X
  674. X    count = at_ptr->a_count;
  675. X    for (i = 0; i < count;) {
  676. X        index = (int)at_ptr->actions[i].index;
  677. X        offset = (*ft[index].func)(&(at_ptr->actions[i].arg));
  678. X        if (is_jump(index))
  679. X            i += offset;
  680. X        else
  681. X            i++;
  682. X    }
  683. X}
  684. X
  685. X/*
  686. X
  687. X 'ft' is a table containing C functions within this program. 
  688. X
  689. X An 'action_table' contains pointers to these functions and arguments to be
  690. X passed to them. 
  691. X
  692. X at_ptr is a pointer to the action table which must be executed (evaluated)
  693. X
  694. X so the iterated line exectues the function indexed by the at_ptr and 
  695. X passes the address of the argument which is pointed to by the arg_ptr 
  696. X
  697. X*/
  698. *-*-END-of-eval.c-*-*
  699. echo x - parse.c
  700. sed 's/^X//' >parse.c <<'*-*-END-of-parse.c-*-*'
  701. X/* GNUPLOT - parse.c */
  702. X/*
  703. X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  704. X *
  705. X * Permission to use, copy, and distribute this software and its
  706. X * documentation for any purpose with or without fee is hereby granted, 
  707. X * provided that the above copyright notice appear in all copies and 
  708. X * that both that copyright notice and this permission notice appear 
  709. X * in supporting documentation.
  710. X *
  711. X * Permission to modify the software is granted, but not the right to
  712. X * distribute the modified code.  Modifications are to be distributed 
  713. X * as patches to released version.
  714. X *  
  715. X * This software  is provided "as is" without express or implied warranty.
  716. X * 
  717. X *
  718. X * AUTHORS
  719. X * 
  720. X *   Original Software:
  721. X *     Thomas Williams,  Colin Kelley.
  722. X * 
  723. X *   Gnuplot 2.0 additions:
  724. X *       Russell Lang, Dave Kotz, John Campbell.
  725. X * 
  726. X * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  727. X * 
  728. X */
  729. X
  730. X#include <stdio.h>
  731. X#include <setjmp.h>
  732. X#include <signal.h>
  733. X#include <errno.h>
  734. X#include "plot.h"
  735. X
  736. X#ifndef vms
  737. X#ifndef __ZTC__
  738. Xextern int errno;
  739. X#endif
  740. X#endif
  741. X
  742. Xextern int num_tokens,c_token;
  743. Xextern struct lexical_unit token[];
  744. Xextern char c_dummy_var[];            /* name of current dummy variable */
  745. Xextern struct udft_entry *dummy_func;    /* pointer to dummy variable's func */
  746. X
  747. Xstruct value *pop(),*integer(),*complex();
  748. Xstruct at_type *temp_at(), *perm_at();
  749. Xstruct udft_entry *add_udf();
  750. Xstruct udvt_entry *add_udv();
  751. Xunion argument *add_action();
  752. X
  753. Xstruct at_type at;
  754. Xstatic jmp_buf fpe_env;
  755. X
  756. X#define dummy (struct value *) 0
  757. X
  758. X#ifdef __TURBOC__
  759. Xvoid fpe()
  760. X#else
  761. X#ifdef __ZTC__
  762. Xvoid fpe(an_int)
  763. Xint an_int;
  764. X#else
  765. Xfpe()
  766. X#endif
  767. X#endif
  768. X{
  769. X#ifdef PC    /* thanks to lotto@wjh12.UUCP for telling us about this  */
  770. X    _fpreset();
  771. X#endif
  772. X    (void) signal(SIGFPE, fpe);
  773. X    undefined = TRUE;
  774. X    longjmp(fpe_env, TRUE);
  775. X}
  776. X
  777. X
  778. Xevaluate_at(at_ptr,val_ptr)
  779. Xstruct at_type *at_ptr;
  780. Xstruct value *val_ptr;
  781. X{
  782. X    undefined = FALSE;
  783. X    errno = 0;
  784. X    reset_stack();
  785. X    if (setjmp(fpe_env))
  786. X        return;                /* just bail out */
  787. X    (void) signal(SIGFPE, fpe);    /* catch core dumps on FPEs */
  788. X
  789. X    execute_at(at_ptr);
  790. X
  791. X    (void) signal(SIGFPE, SIG_DFL);
  792. X
  793. X    if (errno == EDOM || errno == ERANGE) {
  794. X        undefined = TRUE;
  795. X    } else {
  796. X        (void) pop(val_ptr);
  797. X        check_stack();
  798. X    }
  799. X}
  800. X
  801. X
  802. Xstruct value *
  803. Xconst_express(valptr)
  804. Xstruct value *valptr;
  805. X{
  806. Xregister int tkn = c_token;
  807. X    if (END_OF_COMMAND)
  808. X        int_error("constant expression required",c_token);
  809. X    evaluate_at(temp_at(),valptr);    /* run it and send answer back */
  810. X    if (undefined) {
  811. X        int_error("undefined value",tkn);
  812. X    }
  813. X    return(valptr);
  814. X}
  815. X
  816. X
  817. Xstruct at_type *
  818. Xtemp_at()    /* build a static action table and return its pointer */
  819. X{
  820. X    at.a_count = 0;        /* reset action table !!! */
  821. X    express();
  822. X    return(&at);
  823. X}
  824. X
  825. X
  826. X/* build an action table, put it in dynamic memory, and return its pointer */
  827. X
  828. Xstruct at_type *
  829. Xperm_at()
  830. X{
  831. Xregister struct at_type *at_ptr;
  832. Xregister unsigned int len;
  833. X
  834. X    (void) temp_at();
  835. X    len = sizeof(struct at_type) -
  836. X        (MAX_AT_LEN - at.a_count)*sizeof(struct at_entry);
  837. X    at_ptr = (struct at_type *) alloc(len, "action table");
  838. X     (void) memcpy(at_ptr,&at,len);
  839. X    return(at_ptr);
  840. X}
  841. X
  842. X
  843. X#ifdef NOCOPY
  844. X/*
  845. X * cheap and slow version of memcpy() in case you don't have one
  846. X */
  847. Xmemcpy(dest,src,len)
  848. Xchar *dest,*src;
  849. Xunsigned int len;
  850. X{
  851. X    while (len--)
  852. X        *dest++ = *src++;
  853. X}
  854. X#endif /* NOCOPY */
  855. X
  856. X
  857. Xexpress()  /* full expressions */
  858. X{
  859. X    xterm();
  860. X    xterms();
  861. X}
  862. X
  863. Xxterm()  /* ? : expressions */
  864. X{
  865. X    aterm();
  866. X    aterms();
  867. X}
  868. X
  869. X
  870. Xaterm()
  871. X{
  872. X    bterm();
  873. X    bterms();
  874. X}
  875. X
  876. X
  877. Xbterm()
  878. X{
  879. X    cterm();
  880. X    cterms();
  881. X}
  882. X
  883. X
  884. Xcterm()
  885. X{
  886. X    dterm();
  887. X    dterms();
  888. X}
  889. X
  890. X
  891. Xdterm()
  892. X{    
  893. X    eterm();
  894. X    eterms();
  895. X}
  896. X
  897. X
  898. Xeterm()
  899. X{
  900. X    fterm();
  901. X    fterms();
  902. X}
  903. X
  904. X
  905. Xfterm()
  906. X{
  907. X    gterm();
  908. X    gterms();
  909. X}
  910. X
  911. X
  912. Xgterm()
  913. X{
  914. X    hterm();
  915. X    hterms();
  916. X}
  917. X
  918. X
  919. Xhterm()
  920. X{
  921. X    unary(); /* - things */
  922. X    iterms(); /* * / % */
  923. X}
  924. X
  925. X
  926. Xfactor()
  927. X{
  928. Xregister int value;
  929. X
  930. X    if (equals(c_token,"(")) {
  931. X        c_token++;
  932. X        express();
  933. X        if (!equals(c_token,")"))
  934. X            int_error("')' expected",c_token);
  935. X        c_token++;
  936. X    }
  937. X    else if (isnumber(c_token)) {
  938. X        convert(&(add_action(PUSHC)->v_arg),c_token);
  939. X        c_token++;
  940. X    }
  941. X    else if (isletter(c_token)) {
  942. X        if ((c_token+1 < num_tokens)  && equals(c_token+1,"(")) {
  943. X            value = standard(c_token);
  944. X            if (value) {    /* it's a standard function */
  945. X                c_token += 2;
  946. X                express();
  947. X                if (!equals(c_token,")"))
  948. X                    int_error("')' expected",c_token);
  949. X                c_token++;
  950. X                (void) add_action(value);
  951. X            }
  952. X            else {
  953. X                value = c_token;
  954. X                c_token += 2;
  955. X                express();
  956. X                if (!equals(c_token,")"))
  957. X                    int_error("')' expected",c_token);
  958. X                c_token++;
  959. X                add_action(CALL)->udf_arg = add_udf(value);
  960. X            }
  961. X        }
  962. X        else {
  963. X            if (equals(c_token,c_dummy_var)) {
  964. X                c_token++;
  965. X                add_action(PUSHD)->udf_arg = dummy_func;
  966. X            }
  967. X            else {
  968. X                add_action(PUSH)->udv_arg = add_udv(c_token);
  969. X                c_token++;
  970. X            }
  971. X        }
  972. X    } /* end if letter */
  973. X    else
  974. X        int_error("invalid expression ",c_token);
  975. X
  976. X    /* add action code for ! (factorial) operator */
  977. X    while (equals(c_token,"!")) {
  978. X        c_token++;
  979. X        (void) add_action(FACTORIAL);
  980. X    }
  981. X    /* add action code for ** operator */
  982. X    if (equals(c_token,"**")) {
  983. X            c_token++;
  984. X            unary();
  985. X            (void) add_action(POWER);
  986. X    }
  987. X
  988. X}
  989. X
  990. X
  991. X
  992. Xxterms()
  993. X{  /* create action code for ? : expressions */
  994. X
  995. X    if (equals(c_token,"?")) {
  996. X        register int savepc1, savepc2;
  997. X        register union argument *argptr1,*argptr2;
  998. X        c_token++;
  999. X        savepc1 = at.a_count;
  1000. X        argptr1 = add_action(JTERN);
  1001. X        express();
  1002. X        if (!equals(c_token,":"))
  1003. X            int_error("expecting ':'",c_token);
  1004. X        c_token++;
  1005. X        savepc2 = at.a_count;
  1006. X        argptr2 = add_action(JUMP);
  1007. X        argptr1->j_arg = at.a_count - savepc1;
  1008. X        express();
  1009. X        argptr2->j_arg = at.a_count - savepc2;
  1010. X    }
  1011. X}
  1012. X
  1013. X
  1014. Xaterms()
  1015. X{  /* create action codes for || operator */
  1016. X
  1017. X    while (equals(c_token,"||")) {
  1018. X        register int savepc;
  1019. X        register union argument *argptr;
  1020. X        c_token++;
  1021. X        savepc = at.a_count;
  1022. X        argptr = add_action(JUMPNZ);    /* short-circuit if already TRUE */
  1023. X        aterm();
  1024. X        argptr->j_arg = at.a_count - savepc;/* offset for jump */
  1025. X        (void) add_action(BOOL);
  1026. X    }
  1027. X}
  1028. X
  1029. X
  1030. Xbterms()
  1031. X{ /* create action code for && operator */
  1032. X
  1033. X    while (equals(c_token,"&&")) {
  1034. X        register int savepc;
  1035. X        register union argument *argptr;
  1036. X        c_token++;
  1037. X        savepc = at.a_count;
  1038. X        argptr = add_action(JUMPZ);    /* short-circuit if already FALSE */
  1039. X        bterm();
  1040. X        argptr->j_arg = at.a_count - savepc;/* offset for jump */
  1041. X        (void) add_action(BOOL);
  1042. X    }
  1043. X}
  1044. X
  1045. X
  1046. Xcterms()
  1047. X{ /* create action code for | operator */
  1048. X
  1049. X    while (equals(c_token,"|")) {
  1050. X        c_token++;
  1051. X        cterm();
  1052. X        (void) add_action(BOR);
  1053. X    }
  1054. X}
  1055. X
  1056. X
  1057. Xdterms()
  1058. X{ /* create action code for ^ operator */
  1059. X
  1060. X    while (equals(c_token,"^")) {
  1061. X        c_token++;
  1062. X        dterm();
  1063. X        (void) add_action(XOR);
  1064. X    }
  1065. X}
  1066. X
  1067. X
  1068. Xeterms()
  1069. X{ /* create action code for & operator */
  1070. X
  1071. X    while (equals(c_token,"&")) {
  1072. X        c_token++;
  1073. X        eterm();
  1074. X        (void) add_action(BAND);
  1075. X    }
  1076. X}
  1077. X
  1078. X
  1079. Xfterms()
  1080. X{ /* create action codes for == and != operators */
  1081. X
  1082. X    while (TRUE) {
  1083. X        if (equals(c_token,"==")) {
  1084. X            c_token++;
  1085. X            fterm();
  1086. X            (void) add_action(EQ);
  1087. X        }
  1088. X        else if (equals(c_token,"!=")) {
  1089. X            c_token++;
  1090. X            fterm();
  1091. X            (void) add_action(NE);
  1092. X        }
  1093. X        else break;
  1094. X    }
  1095. X}
  1096. X
  1097. X
  1098. Xgterms()
  1099. X{ /* create action code for < > >= or <= operators */
  1100. X    
  1101. X    while (TRUE) {
  1102. X        /* I hate "else if" statements */
  1103. X        if (equals(c_token,">")) {
  1104. X            c_token++;
  1105. X            gterm();
  1106. X            (void) add_action(GT);
  1107. X        }
  1108. X        else if (equals(c_token,"<")) {
  1109. X            c_token++;
  1110. X            gterm();
  1111. X            (void) add_action(LT);
  1112. X        }        
  1113. X        else if (equals(c_token,">=")) {
  1114. X            c_token++;
  1115. X            gterm();
  1116. X            (void) add_action(GE);
  1117. X        }
  1118. X        else if (equals(c_token,"<=")) {
  1119. X            c_token++;
  1120. X            gterm();
  1121. X            (void) add_action(LE);
  1122. X        }
  1123. X        else break;
  1124. X    }
  1125. X
  1126. X}
  1127. X
  1128. X
  1129. X
  1130. Xhterms()
  1131. X{ /* create action codes for + and - operators */
  1132. X
  1133. X    while (TRUE) {
  1134. X            if (equals(c_token,"+")) {
  1135. X                c_token++;
  1136. X                hterm();
  1137. X                (void) add_action(PLUS);
  1138. X            }
  1139. X            else if (equals(c_token,"-")) {
  1140. X                c_token++;
  1141. X                hterm();
  1142. X                (void) add_action(MINUS);
  1143. X            }
  1144. X            else break;
  1145. X    }
  1146. X}
  1147. X
  1148. X
  1149. Xiterms()
  1150. X{ /* add action code for * / and % operators */
  1151. X
  1152. X    while (TRUE) {
  1153. X            if (equals(c_token,"*")) {
  1154. X                c_token++;
  1155. X                unary();
  1156. X                (void) add_action(MULT);
  1157. X            }
  1158. X            else if (equals(c_token,"/")) {
  1159. X                c_token++;
  1160. X                unary();
  1161. X                (void) add_action(DIV);
  1162. X            }
  1163. X            else if (equals(c_token,"%")) {
  1164. X                c_token++;
  1165. X                unary();
  1166. X                (void) add_action(MOD);
  1167. X            }
  1168. X            else break;
  1169. X    }
  1170. X}
  1171. X
  1172. X
  1173. Xunary()
  1174. X{ /* add code for unary operators */
  1175. X    if (equals(c_token,"!")) {
  1176. X        c_token++;
  1177. X        unary();
  1178. X        (void) add_action(LNOT);
  1179. X    }
  1180. X    else if (equals(c_token,"~")) {
  1181. X        c_token++;
  1182. X        unary();
  1183. X        (void) add_action(BNOT);
  1184. X    }
  1185. X    else if (equals(c_token,"-")) {
  1186. X        c_token++;
  1187. X        unary();
  1188. X        (void) add_action(UMINUS);
  1189. X    }
  1190. X    else
  1191. X        factor();
  1192. X}
  1193. *-*-END-of-parse.c-*-*
  1194. echo x - plot.c
  1195. sed 's/^X//' >plot.c <<'*-*-END-of-plot.c-*-*'
  1196. X/* GNUPLOT - plot.c */
  1197. X/*
  1198. X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  1199. X *
  1200. X * Permission to use, copy, and distribute this software and its
  1201. X * documentation for any purpose with or without fee is hereby granted, 
  1202. X * provided that the above copyright notice appear in all copies and 
  1203. X * that both that copyright notice and this permission notice appear 
  1204. X * in supporting documentation.
  1205. X *
  1206. X * Permission to modify the software is granted, but not the right to
  1207. X * distribute the modified code.  Modifications are to be distributed 
  1208. X * as patches to released version.
  1209. X *  
  1210. X * This software  is provided "as is" without express or implied warranty.
  1211. X * 
  1212. X *
  1213. X * AUTHORS
  1214. X * 
  1215. X *   Original Software:
  1216. X *     Thomas Williams,  Colin Kelley.
  1217. X * 
  1218. X *   Gnuplot 2.0 additions:
  1219. X *       Russell Lang, Dave Kotz, John Campbell.
  1220. X * 
  1221. X * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  1222. X * 
  1223. X */
  1224. X
  1225. X#include <stdio.h>
  1226. X#include <setjmp.h>
  1227. X#include <signal.h>
  1228. X#include "plot.h"
  1229. X#include "setshow.h"
  1230. X#ifdef MSDOS
  1231. X#include <io.h>
  1232. X#endif
  1233. X#ifdef vms
  1234. X#include <unixio.h>
  1235. X#endif
  1236. X#ifdef __TURBOC__
  1237. X#include <graphics.h>
  1238. X#endif
  1239. X
  1240. Xextern char *getenv(),*strcat(),*strcpy(),*strncpy();
  1241. X
  1242. Xextern char input_line[];
  1243. Xextern int c_token;
  1244. Xextern FILE *outfile;
  1245. Xextern int term;
  1246. X
  1247. XBOOLEAN interactive = TRUE;    /* FALSE if stdin not a terminal */
  1248. Xchar *infile_name = NULL;    /* name of command file; NULL if terminal */
  1249. X
  1250. X#ifndef STDOUT
  1251. X#define STDOUT 1
  1252. X#endif
  1253. X
  1254. Xjmp_buf env;
  1255. X
  1256. Xstruct value *integer(),*complex();
  1257. X
  1258. X
  1259. Xextern f_push(),f_pushc(),f_pushd(),f_call(),f_lnot(),f_bnot(),f_uminus()
  1260. X    ,f_lor(),f_land(),f_bor(),f_xor(),f_band(),f_eq(),f_ne(),f_gt(),f_lt(),
  1261. X    f_ge(),f_le(),f_plus(),f_minus(),f_mult(),f_div(),f_mod(),f_power(),
  1262. X    f_factorial(),f_bool(),f_jump(),f_jumpz(),f_jumpnz(),f_jtern();
  1263. X
  1264. Xextern f_real(),f_imag(),f_arg(),f_conjg(),f_sin(),f_cos(),f_tan(),f_asin(),
  1265. X    f_acos(),f_atan(),f_sinh(),f_cosh(),f_tanh(),f_int(),f_abs(),f_sgn(),
  1266. X    f_sqrt(),f_exp(),f_log10(),f_log(),f_besj0(),f_besj1(),f_besy0(),f_besy1(),
  1267. X#ifdef GAMMA
  1268. X    f_gamma(),
  1269. X#endif
  1270. X    f_floor(),f_ceil();
  1271. X
  1272. X
  1273. Xstruct ft_entry ft[] = {    /* built-in function table */
  1274. X
  1275. X/* internal functions: */
  1276. X    {"push", f_push},    {"pushc", f_pushc},    {"pushd", f_pushd},
  1277. X    {"call", f_call},    {"lnot", f_lnot},    {"bnot", f_bnot},
  1278. X    {"uminus", f_uminus},                    {"lor", f_lor},
  1279. X    {"land", f_land},    {"bor", f_bor},        {"xor", f_xor},
  1280. X    {"band", f_band},    {"eq", f_eq},        {"ne", f_ne},
  1281. X    {"gt", f_gt},        {"lt", f_lt},        {"ge", f_ge},
  1282. X    {"le", f_le},        {"plus", f_plus},    {"minus", f_minus},
  1283. X    {"mult", f_mult},    {"div", f_div},        {"mod", f_mod},
  1284. X    {"power", f_power}, {"factorial", f_factorial},
  1285. X    {"bool", f_bool},    {"jump", f_jump},    {"jumpz", f_jumpz},
  1286. X    {"jumpnz",f_jumpnz},{"jtern", f_jtern},
  1287. X
  1288. X/* standard functions: */
  1289. X    {"real", f_real},    {"imag", f_imag},    {"arg", f_arg},
  1290. X    {"conjg", f_conjg}, {"sin", f_sin},        {"cos", f_cos},
  1291. X    {"tan", f_tan},        {"asin", f_asin},    {"acos", f_acos},
  1292. X    {"atan", f_atan},    {"sinh", f_sinh},    {"cosh", f_cosh},
  1293. X    {"tanh", f_tanh},    {"int", f_int},        {"abs", f_abs},
  1294. X    {"sgn", f_sgn},        {"sqrt", f_sqrt},    {"exp", f_exp},
  1295. X    {"log10", f_log10},    {"log", f_log},        {"besj0", f_besj0},
  1296. X    {"besj1", f_besj1},    {"besy0", f_besy0},    {"besy1", f_besy1},
  1297. X#ifdef GAMMA
  1298. X     {"gamma", f_gamma},
  1299. X#endif
  1300. X    {"floor", f_floor},    {"ceil", f_ceil},
  1301. X    {NULL, NULL}
  1302. X};
  1303. X
  1304. Xstatic struct udvt_entry udv_pi = {NULL, "pi",FALSE};
  1305. X                                    /* first in linked list */
  1306. Xstruct udvt_entry *first_udv = &udv_pi;
  1307. Xstruct udft_entry *first_udf = NULL;
  1308. X
  1309. X
  1310. X
  1311. X#ifdef vms
  1312. X
  1313. X#define HOME "sys$login:"
  1314. X
  1315. X#else /* vms */
  1316. X#ifdef MSDOS
  1317. X
  1318. X#define HOME "GNUPLOT"
  1319. X
  1320. X#else /* MSDOS */
  1321. X
  1322. X#define HOME "HOME"
  1323. X
  1324. X#endif /* MSDOS */
  1325. X#endif /* vms */
  1326. X
  1327. X#ifdef unix
  1328. X#define PLOTRC ".gnuplot"
  1329. X#else
  1330. X#define PLOTRC "gnuplot.ini"
  1331. X#endif
  1332. X
  1333. X#ifdef __TURBOC__
  1334. Xvoid tc_interrupt()
  1335. X#else
  1336. Xinter()
  1337. X#endif
  1338. X{
  1339. X#ifdef MSDOS
  1340. X#ifdef __TURBOC__
  1341. X    (void) signal(SIGINT, tc_interrupt);
  1342. X#else
  1343. X    void ss_interrupt();
  1344. X    (void) signal(SIGINT, ss_interrupt);
  1345. X#endif
  1346. X#else  /* MSDOS */
  1347. X    (void) signal(SIGINT, inter);
  1348. X#endif  /* MSDOS */
  1349. X    (void) signal(SIGFPE, SIG_DFL);    /* turn off FPE trapping */
  1350. X    if (term && term_init)
  1351. X        (*term_tbl[term].text)();    /* hopefully reset text mode */
  1352. X    (void) fflush(outfile);
  1353. X    (void) putc('\n',stderr);
  1354. X    longjmp(env, TRUE);        /* return to prompt */
  1355. X}
  1356. X
  1357. X
  1358. Xmain(argc, argv)
  1359. X    int argc;
  1360. X    char **argv;
  1361. X{
  1362. X/* Register the Borland Graphics Interface drivers. If they have been */
  1363. X/* included by the linker.                                            */
  1364. X#ifdef __TURBOC__
  1365. Xregisterbgidriver(CGA_driver);
  1366. Xregisterbgidriver(EGAVGA_driver);
  1367. Xregisterbgidriver(Herc_driver);
  1368. X#endif
  1369. X
  1370. X    setbuf(stderr,(char *)NULL);
  1371. X    outfile = stdout;
  1372. X    (void) complex(&udv_pi.udv_value, Pi, 0.0);
  1373. X
  1374. X     interactive = FALSE;
  1375. X     init_terminal();        /* can set term type if it likes */
  1376. X
  1377. X     interactive = isatty(fileno(stdin));
  1378. X     if (argc > 1)
  1379. X      interactive = FALSE;
  1380. X
  1381. X     if (interactive)
  1382. X      show_version();
  1383. X
  1384. X    if (!setjmp(env)) {
  1385. X        /* first time */
  1386. X        interrupt_setup();
  1387. X        load_rcfile();
  1388. X
  1389. X        if (interactive && term != 0)    /* not unknown */
  1390. X         fprintf(stderr, "\nTerminal type set to '%s'\n", 
  1391. X                term_tbl[term].name);
  1392. X    } else {    
  1393. X        /* come back here from int_error() */
  1394. X        load_file_error();    /* if we were in load_file(), cleanup */
  1395. X#ifdef vms
  1396. X        /* after catching interrupt */
  1397. X        /* VAX stuffs up stdout on SIGINT while writing to stdout,
  1398. X          so reopen stdout. */
  1399. X        if (outfile = stdout) {
  1400. X           if ( (stdout = freopen("SYS$OUTPUT","w",stdout))  == NULL) {
  1401. X              /* couldn't reopen it so try opening it instead */
  1402. X              if ( (stdout = fopen("SYS$OUTPUT","w"))  == NULL) {
  1403. X                 /* don't use int_error here - causes infinite loop! */
  1404. X                 fprintf(stderr,"Error opening SYS$OUTPUT as stdout\n");
  1405. X              }
  1406. X           }
  1407. X           outfile = stdout;
  1408. X        }
  1409. X#endif                    /* VMS */
  1410. X        if (!interactive)
  1411. X         done(IO_ERROR);            /* exit on non-interactive error */
  1412. X    }
  1413. X
  1414. X     if (argc > 1) {
  1415. X        /* load filenames given as arguments */
  1416. X        while (--argc > 0) {
  1417. X           ++argv;
  1418. X           c_token = NO_CARET; /* in case of file not found */
  1419. X           load_file(fopen(*argv,"r"), *argv);    
  1420. X        }
  1421. X    } else {
  1422. X        /* take commands from stdin */
  1423. X        while(TRUE)
  1424. X         com_line();
  1425. X    }
  1426. X
  1427. X     done(IO_SUCCESS);
  1428. X}
  1429. X
  1430. X/* Set up to catch interrupts */
  1431. Xinterrupt_setup()
  1432. X{
  1433. X#ifdef MSDOS
  1434. X#ifdef __TURBOC__
  1435. X        (void) signal(SIGINT, tc_interrupt);    /* go there on interrupt char */
  1436. X#else
  1437. X        void ss_interrupt();
  1438. X        save_stack();                /* work-around for MSC 4.0/MSDOS 3.x bug */
  1439. X        (void) signal(SIGINT, ss_interrupt);
  1440. X#endif
  1441. X#else /* MSDOS */
  1442. X        (void) signal(SIGINT, inter);    /* go there on interrupt char */
  1443. X#endif /* MSDOS */
  1444. X}
  1445. X
  1446. X
  1447. X/* Look for a gnuplot start-up file */
  1448. Xload_rcfile()
  1449. X{
  1450. X    register FILE *plotrc;
  1451. X    static char home[80];
  1452. X    static char rcfile[sizeof(PLOTRC)+80];
  1453. X
  1454. X    /* Look for a gnuplot init file in . or home directory */
  1455. X#ifdef vms
  1456. X    (void) strcpy(home,HOME);
  1457. X#else
  1458. X    (void) strcat(strcpy(home,getenv(HOME)),"/");
  1459. X#endif                    /* vms */
  1460. X    (void) strcpy(rcfile, PLOTRC);
  1461. X    plotrc = fopen(rcfile,"r");
  1462. X    if (plotrc == (FILE *)NULL) {
  1463. X       (void) sprintf(rcfile, "%s%s", home, PLOTRC);
  1464. X       plotrc = fopen(rcfile,"r");
  1465. X    }
  1466. X    if (plotrc)
  1467. X     load_file(plotrc, rcfile);
  1468. X}
  1469. *-*-END-of-plot.c-*-*
  1470. echo x - scanner.c
  1471. sed 's/^X//' >scanner.c <<'*-*-END-of-scanner.c-*-*'
  1472. X/* GNUPLOT - scanner.c */
  1473. X/*
  1474. X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  1475. X *
  1476. X * Permission to use, copy, and distribute this software and its
  1477. X * documentation for any purpose with or without fee is hereby granted, 
  1478. X * provided that the above copyright notice appear in all copies and 
  1479. X * that both that copyright notice and this permission notice appear 
  1480. X * in supporting documentation.
  1481. X *
  1482. X * Permission to modify the software is granted, but not the right to
  1483. X * distribute the modified code.  Modifications are to be distributed 
  1484. X * as patches to released version.
  1485. X *  
  1486. X * This software  is provided "as is" without express or implied warranty.
  1487. X * 
  1488. X *
  1489. X * AUTHORS
  1490. X * 
  1491. X *   Original Software:
  1492. X *     Thomas Williams,  Colin Kelley.
  1493. X * 
  1494. X *   Gnuplot 2.0 additions:
  1495. X *       Russell Lang, Dave Kotz, John Campbell.
  1496. X * 
  1497. X * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  1498. X * 
  1499. X */
  1500. X
  1501. X#include <stdio.h>
  1502. X#include <ctype.h>
  1503. X#include "plot.h"
  1504. X
  1505. X#ifdef vms
  1506. X
  1507. X#include stdio
  1508. X#include descrip
  1509. X#include errno
  1510. X
  1511. X#define MAILBOX "PLOT$MAILBOX"
  1512. X#define pclose(f) fclose(f)
  1513. X
  1514. X#endif /* vms */
  1515. X
  1516. X
  1517. X#define isident(c) (isalnum(c) || (c) == '_')
  1518. X
  1519. X#ifndef STDOUT
  1520. X#define STDOUT 1
  1521. X#endif
  1522. X
  1523. X#define LBRACE '{'
  1524. X#define RBRACE '}'
  1525. X
  1526. X#define APPEND_TOKEN {token[t_num].length++; current++;}
  1527. X
  1528. X#define SCAN_IDENTIFIER while (isident(expression[current + 1]))\
  1529. X                APPEND_TOKEN
  1530. X
  1531. Xextern struct lexical_unit token[MAX_TOKENS];
  1532. X
  1533. Xstatic int t_num;    /* number of token I'm working on */
  1534. X
  1535. Xchar *strcat(), *strcpy(), *strncpy();
  1536. X
  1537. X/*
  1538. X * scanner() breaks expression[] into lexical units, storing them in token[].
  1539. X *   The total number of tokens found is returned as the function value.
  1540. X *   Scanning will stop when '\0' is found in expression[], or when token[]
  1541. X *     is full.
  1542. X *
  1543. X *     Scanning is performed by following rules:
  1544. X *
  1545. X *        Current char    token should contain
  1546. X *     -------------    -----------------------
  1547. X *        1.  alpha        all following alpha-numerics
  1548. X *        2.  digit        0 or more following digits, 0 or 1 decimal point,
  1549. X *                          0 or more digits, 0 or 1 'e' or 'E',
  1550. X *                          0 or more digits.
  1551. X *        3.  ^,+,-,/        only current char
  1552. X *            %,~,(,)
  1553. X *            [,],;,:,
  1554. X *            ?,comma
  1555. X *        4.  &,|,=,*        current char; also next if next is same
  1556. X *        5.  !,<,>        current char; also next if next is =
  1557. X *        6.  ", '        all chars up until matching quote
  1558. X *        7.  #          this token cuts off scanning of the line (DFK).
  1559. X *
  1560. X *        white space between tokens is ignored
  1561. X */
  1562. Xscanner(expression)
  1563. Xchar expression[];
  1564. X{
  1565. Xregister int current;    /* index of current char in expression[] */
  1566. Xregister int quote;
  1567. Xchar brace;
  1568. X
  1569. X    for (current = t_num = 0;
  1570. X        t_num < MAX_TOKENS && expression[current] != '\0';
  1571. X        current++) {
  1572. Xagain:
  1573. X        if (isspace(expression[current]))
  1574. X            continue;                        /* skip the whitespace */
  1575. X        token[t_num].start_index = current;
  1576. X        token[t_num].length = 1;
  1577. X        token[t_num].is_token = TRUE;    /* to start with...*/
  1578. X
  1579. X        if (expression[current] == '`') {
  1580. X            substitute(&expression[current],MAX_LINE_LEN - current);
  1581. X            goto again;
  1582. X        }
  1583. X        if (isalpha(expression[current])) {
  1584. X            SCAN_IDENTIFIER;
  1585. X        } else if (isdigit(expression[current]) || expression[current] == '.'){
  1586. X            token[t_num].is_token = FALSE;
  1587. X            token[t_num].length = get_num(&expression[current]);
  1588. X            current += (token[t_num].length - 1);
  1589. X        } else if (expression[current] == LBRACE) {
  1590. X            token[t_num].is_token = FALSE;
  1591. X            token[t_num].l_val.type = CMPLX;
  1592. X            if ((sscanf(&expression[++current],"%lf , %lf %c",
  1593. X                &token[t_num].l_val.v.cmplx_val.real,
  1594. X                &token[t_num].l_val.v.cmplx_val.imag,
  1595. X                &brace) != 3) || (brace != RBRACE))
  1596. X                    int_error("invalid complex constant",t_num);
  1597. X            token[t_num].length += 2;
  1598. X            while (expression[++current] != RBRACE) {
  1599. X                token[t_num].length++;
  1600. X                if (expression[current] == '\0')            /* { for vi % */
  1601. X                    int_error("no matching '}'", t_num);
  1602. X            }
  1603. X        } else if (expression[current] == '\'' || expression[current] == '\"'){
  1604. X            token[t_num].length++;
  1605. X            quote = expression[current];
  1606. X            while (expression[++current] != quote) {
  1607. X                if (!expression[current]) {
  1608. X                    expression[current] = quote;
  1609. X                    expression[current+1] = '\0';
  1610. X                    break;
  1611. X                } else
  1612. X                    token[t_num].length++;
  1613. X            }
  1614. X        } else switch (expression[current]) {
  1615. X             case '#':        /* DFK: add comments to gnuplot */
  1616. X                  goto endline; /* ignore the rest of the line */
  1617. X            case '^':
  1618. X            case '+':
  1619. X            case '-':
  1620. X            case '/':
  1621. X            case '%':
  1622. X            case '~':
  1623. X            case '(':
  1624. X            case ')':
  1625. X            case '[':
  1626. X            case ']':
  1627. X            case ';':
  1628. X            case ':':
  1629. X            case '?':
  1630. X            case ',':
  1631. X                break;
  1632. X            case '&':
  1633. X            case '|':
  1634. X            case '=':
  1635. X            case '*':
  1636. X                if (expression[current] == expression[current + 1])
  1637. X                    APPEND_TOKEN;
  1638. X                break;
  1639. X            case '!':
  1640. X            case '<':
  1641. X            case '>':
  1642. X                if (expression[current + 1] == '=')
  1643. X                    APPEND_TOKEN;
  1644. X                break;
  1645. X            default:
  1646. X                int_error("invalid character",t_num);
  1647. X            }
  1648. X        ++t_num;    /* next token if not white space */
  1649. X    }
  1650. X
  1651. Xendline:                    /* comments jump here to ignore line */
  1652. X
  1653. X/* Now kludge an extra token which points to '\0' at end of expression[].
  1654. X   This is useful so printerror() looks nice even if we've fallen off the
  1655. X   line. */
  1656. X
  1657. X        token[t_num].start_index = current;
  1658. X        token[t_num].length = 0;
  1659. X    return(t_num);
  1660. X}
  1661. X
  1662. X
  1663. Xget_num(str)
  1664. Xchar str[];
  1665. X{
  1666. Xdouble atof();
  1667. Xregister int count = 0;
  1668. Xlong atol();
  1669. Xregister long lval;
  1670. X
  1671. X    token[t_num].is_token = FALSE;
  1672. X    token[t_num].l_val.type = INT;        /* assume unless . or E found */
  1673. X    while (isdigit(str[count]))
  1674. X        count++;
  1675. X    if (str[count] == '.') {
  1676. X        token[t_num].l_val.type = CMPLX;
  1677. X        while (isdigit(str[++count]))    /* swallow up digits until non-digit */
  1678. X            ;
  1679. X        /* now str[count] is other than a digit */
  1680. X    }
  1681. X    if (str[count] == 'e' || str[count] == 'E') {
  1682. X        token[t_num].l_val.type = CMPLX;
  1683. X/* modified if statement to allow + sign in exponent
  1684. X   rjl 26 July 1988 */
  1685. X        count++;
  1686. X        if (str[count] == '-' || str[count] == '+')
  1687. X            count++;
  1688. X        if (!isdigit(str[count])) {
  1689. X            token[t_num].start_index += count;
  1690. X            int_error("expecting exponent",t_num);
  1691. X        }
  1692. X        while (isdigit(str[++count]))
  1693. X            ;
  1694. X    }
  1695. X    if (token[t_num].l_val.type == INT) {
  1696. X         lval = atol(str);
  1697. X        if ((token[t_num].l_val.v.int_val = lval) != lval)
  1698. X            int_error("integer overflow; change to floating point",t_num);
  1699. X    } else {
  1700. X        token[t_num].l_val.v.cmplx_val.imag = 0.0;
  1701. X        token[t_num].l_val.v.cmplx_val.real = atof(str);
  1702. X    }
  1703. X    return(count);
  1704. X}
  1705. X
  1706. X
  1707. X#ifdef MSDOS
  1708. X
  1709. X#ifdef __ZTC__
  1710. Xsubstitute(char *str,int max)
  1711. X#else
  1712. Xsubstitute()
  1713. X#endif
  1714. X{
  1715. X    int_error("substitution not supported by MS-DOS!",t_num);
  1716. X}
  1717. X
  1718. X#else /* MSDOS */
  1719. X
  1720. Xsubstitute(str,max)            /* substitute output from ` ` */
  1721. Xchar *str;
  1722. Xint max;
  1723. X{
  1724. Xregister char *last;
  1725. Xregister int i,c;
  1726. Xregister FILE *f;
  1727. XFILE *popen();
  1728. Xstatic char pgm[MAX_LINE_LEN+1],output[MAX_LINE_LEN+1];
  1729. X
  1730. X#ifdef vms
  1731. Xint chan;
  1732. Xstatic $DESCRIPTOR(pgmdsc,pgm);
  1733. Xstatic $DESCRIPTOR(lognamedsc,MAILBOX);
  1734. X#endif /* vms */
  1735. X
  1736. X    i = 0;
  1737. X    last = str;
  1738. X    while (*(++last) != '`') {
  1739. X        if (*last == '\0')
  1740. X            int_error("unmatched `",t_num);
  1741. X        pgm[i++] = *last;
  1742. X    }
  1743. X    pgm[i] = '\0';        /* end with null */
  1744. X    max -= strlen(last);    /* max is now the max length of output sub. */
  1745. X  
  1746. X#ifdef vms
  1747. X      pgmdsc.dsc$w_length = i;
  1748. X       if (!((vaxc$errno = sys$crembx(0,&chan,0,0,0,0,&lognamedsc)) & 1))
  1749. X           os_error("sys$crembx failed",NO_CARET);
  1750. X   
  1751. X       if (!((vaxc$errno = lib$spawn(&pgmdsc,0,&lognamedsc,&1)) & 1))
  1752. X           os_error("lib$spawn failed",NO_CARET);
  1753. X   
  1754. X       if ((f = fopen(MAILBOX,"r")) == NULL)
  1755. X           os_error("mailbox open failed",NO_CARET);
  1756. X#else /* vms */
  1757. X      if ((f = popen(pgm,"r")) == NULL)
  1758. X          os_error("popen failed",NO_CARET);
  1759. X#endif /* vms */
  1760. X
  1761. X    i = 0;
  1762. X    while ((c = getc(f)) != EOF) {
  1763. X        output[i++] = ((c == '\n') ? ' ' : c);    /* newlines become blanks*/
  1764. X        if (i == max) {
  1765. X            (void) pclose(f);
  1766. X            int_error("substitution overflow", t_num);
  1767. X        }
  1768. X    }
  1769. X    (void) pclose(f);
  1770. X    if (i + strlen(last) > max)
  1771. X        int_error("substitution overflowed rest of line", t_num);
  1772. X    (void) strncpy(output+i,last+1,MAX_LINE_LEN-i);
  1773. X                                    /* tack on rest of line to output */
  1774. X    (void) strcpy(str,output);                /* now replace ` ` with output */
  1775. X    screen_ok = FALSE;
  1776. X}
  1777. X#endif /* MS-DOS */
  1778. *-*-END-of-scanner.c-*-*
  1779. echo x - standard.c
  1780. sed 's/^X//' >standard.c <<'*-*-END-of-standard.c-*-*'
  1781. X/* GNUPLOT - standard.c */
  1782. X/*
  1783. X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  1784. X *
  1785. X * Permission to use, copy, and distribute this software and its
  1786. X * documentation for any purpose with or without fee is hereby granted, 
  1787. X * provided that the above copyright notice appear in all copies and 
  1788. X * that both that copyright notice and this permission notice appear 
  1789. X * in supporting documentation.
  1790. X *
  1791. X * Permission to modify the software is granted, but not the right to
  1792. X * distribute the modified code.  Modifications are to be distributed 
  1793. X * as patches to released version.
  1794. X *  
  1795. X * This software  is provided "as is" without express or implied warranty.
  1796. X * 
  1797. X *
  1798. X * AUTHORS
  1799. X * 
  1800. X *   Original Software:
  1801. X *     Thomas Williams,  Colin Kelley.
  1802. X * 
  1803. X *   Gnuplot 2.0 additions:
  1804. X *       Russell Lang, Dave Kotz, John Campbell.
  1805. X * 
  1806. X * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  1807. X * 
  1808. X */
  1809. X
  1810. X#include <math.h>
  1811. X#include <stdio.h>
  1812. X#include "plot.h"
  1813. X
  1814. X#ifdef vms
  1815. X#include <errno.h>
  1816. X#else
  1817. Xextern int errno;
  1818. X#endif /* vms */
  1819. X
  1820. X
  1821. Xextern struct value stack[STACK_DEPTH];
  1822. Xextern int s_p;
  1823. X
  1824. Xstruct value *pop(), *complex(), *integer();
  1825. X
  1826. Xdouble magnitude(), angle(), real(), imag();
  1827. X
  1828. X
  1829. Xf_real()
  1830. X{
  1831. Xstruct value a;
  1832. X    push( complex(&a,real(pop(&a)), 0.0) );
  1833. X}
  1834. X
  1835. Xf_imag()
  1836. X{
  1837. Xstruct value a;
  1838. X    push( complex(&a,imag(pop(&a)), 0.0) );
  1839. X}
  1840. X
  1841. Xf_arg()
  1842. X{
  1843. Xstruct value a;
  1844. X    push( complex(&a,angle(pop(&a)), 0.0) );
  1845. X}
  1846. X
  1847. Xf_conjg()
  1848. X{
  1849. Xstruct value a;
  1850. X    (void) pop(&a);
  1851. X    push( complex(&a,real(&a),-imag(&a) ));
  1852. X}
  1853. X
  1854. Xf_sin()
  1855. X{
  1856. Xstruct value a;
  1857. X    (void) pop(&a);
  1858. X    push( complex(&a,sin(real(&a))*cosh(imag(&a)), cos(real(&a))*sinh(imag(&a))) );
  1859. X}
  1860. X
  1861. Xf_cos()
  1862. X{
  1863. Xstruct value a;
  1864. X    (void) pop(&a);
  1865. X    push( complex(&a,cos(real(&a))*cosh(imag(&a)), -sin(real(&a))*sinh(imag(&a))));
  1866. X}
  1867. X
  1868. Xf_tan()
  1869. X{
  1870. Xstruct value a;
  1871. Xregister double den;
  1872. X    (void) pop(&a);
  1873. X    if (imag(&a) == 0.0)
  1874. X        push( complex(&a,tan(real(&a)),0.0) );
  1875. X    else {
  1876. X        den = cos(2*real(&a))+cosh(2*imag(&a));
  1877. X        if (den == 0.0) {
  1878. X            undefined = TRUE;
  1879. X            push( &a );
  1880. X        }
  1881. X        else
  1882. X            push( complex(&a,sin(2*real(&a))/den, sinh(2*imag(&a))/den) );
  1883. X    }
  1884. X}
  1885. X
  1886. Xf_asin()
  1887. X{
  1888. Xstruct value a;
  1889. Xregister double alpha, beta, x, y;
  1890. X    (void) pop(&a);
  1891. X    x = real(&a); y = imag(&a);
  1892. X    if (y == 0.0) {
  1893. X        if (fabs(x) > 1.0) {
  1894. X            undefined = TRUE;
  1895. X            push(complex(&a,0.0, 0.0));
  1896. X        } else
  1897. X            push( complex(&a,asin(x),0.0) );
  1898. X    } else {
  1899. X        beta  = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
  1900. X        alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
  1901. X        push( complex(&a,asin(beta), log(alpha + sqrt(alpha*alpha-1))) );
  1902. X    }
  1903. X}
  1904. X
  1905. Xf_acos()
  1906. X{
  1907. Xstruct value a;
  1908. Xregister double alpha, beta, x, y;
  1909. X    (void) pop(&a);
  1910. X    x = real(&a); y = imag(&a);
  1911. X    if (y == 0.0) {
  1912. X        if (fabs(x) > 1.0) {
  1913. X            undefined = TRUE;
  1914. X            push(complex(&a,0.0, 0.0));
  1915. X        } else
  1916. X            push( complex(&a,acos(x),0.0) );
  1917. X    } else {
  1918. X        alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
  1919. X        beta  = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
  1920. X        push( complex(&a,acos(beta), log(alpha + sqrt(alpha*alpha-1))) );
  1921. X    }
  1922. X}
  1923. X
  1924. Xf_atan()
  1925. X{
  1926. Xstruct value a;
  1927. Xregister double x, y;
  1928. X    (void) pop(&a);
  1929. X    x = real(&a); y = imag(&a);
  1930. X    if (y == 0.0)
  1931. X        push( complex(&a,atan(x), 0.0) );
  1932. X    else if (x == 0.0 && fabs(y) == 1.0) {
  1933. X        undefined = TRUE;
  1934. X        push(complex(&a,0.0, 0.0));
  1935. X    } else
  1936. X        push( complex(&a,atan(2*x/(1-x*x-y*y)),
  1937. X                log((x*x+(y+1)*(y+1))/(x*x+(y-1)*(y-1)))/4) );
  1938. X}
  1939. X
  1940. Xf_sinh()
  1941. X{
  1942. Xstruct value a;
  1943. X    (void) pop(&a);
  1944. X    push( complex(&a,sinh(real(&a))*cos(imag(&a)), cosh(real(&a))*sin(imag(&a))) );
  1945. X}
  1946. X
  1947. Xf_cosh()
  1948. X{
  1949. Xstruct value a;
  1950. X    (void) pop(&a);
  1951. X    push( complex(&a,cosh(real(&a))*cos(imag(&a)), sinh(real(&a))*sin(imag(&a))) );
  1952. X}
  1953. X
  1954. Xf_tanh()
  1955. X{
  1956. Xstruct value a;
  1957. Xregister double den;
  1958. X    (void) pop(&a);
  1959. X    den = cosh(2*real(&a)) + cos(2*imag(&a));
  1960. X    push( complex(&a,sinh(2*real(&a))/den, sin(2*imag(&a))/den) );
  1961. X}
  1962. X
  1963. Xf_int()
  1964. X{
  1965. Xstruct value a;
  1966. X    push( integer(&a,(int)real(pop(&a))) );
  1967. X}
  1968. X
  1969. X
  1970. Xf_abs()
  1971. X{
  1972. Xstruct value a;
  1973. X    (void) pop(&a);
  1974. X    switch (a.type) {
  1975. X        case INT:
  1976. X            push( integer(&a,abs(a.v.int_val)) );            
  1977. X            break;
  1978. X        case CMPLX:
  1979. X            push( complex(&a,magnitude(&a), 0.0) );
  1980. X    }
  1981. X}
  1982. X
  1983. Xf_sgn()
  1984. X{
  1985. Xstruct value a;
  1986. X    (void) pop(&a);
  1987. X    switch(a.type) {
  1988. X        case INT:
  1989. X            push( integer(&a,(a.v.int_val > 0) ? 1 : 
  1990. X                    (a.v.int_val < 0) ? -1 : 0) );
  1991. X            break;
  1992. X        case CMPLX:
  1993. X            push( integer(&a,(a.v.cmplx_val.real > 0.0) ? 1 : 
  1994. X                    (a.v.cmplx_val.real < 0.0) ? -1 : 0) );
  1995. X            break;
  1996. X    }
  1997. X}
  1998. X
  1999. X
  2000. Xf_sqrt()
  2001. X{
  2002. Xstruct value a;
  2003. Xregister double mag, ang;
  2004. X    (void) pop(&a);
  2005. X    mag = sqrt(magnitude(&a));
  2006. X    if (imag(&a) == 0.0 && real(&a) < 0.0)
  2007. X        push( complex(&a,0.0,mag) );
  2008. X    else
  2009. X    {
  2010. X        if ( (ang = angle(&a)) < 0.0)
  2011. X            ang += 2*Pi;
  2012. X        ang /= 2;
  2013. X        push( complex(&a,mag*cos(ang), mag*sin(ang)) );
  2014. X    }
  2015. X}
  2016. X
  2017. X
  2018. Xf_exp()
  2019. X{
  2020. Xstruct value a;
  2021. Xregister double mag, ang;
  2022. X    (void) pop(&a);
  2023. X    mag = exp(real(&a));
  2024. X    ang = imag(&a);
  2025. X    push( complex(&a,mag*cos(ang), mag*sin(ang)) );
  2026. X}
  2027. X
  2028. X
  2029. Xf_log10()
  2030. X{
  2031. Xstruct value a;
  2032. Xregister double l10;;
  2033. X    (void) pop(&a);
  2034. X    l10 = log(10.0);    /***** replace with a constant! ******/
  2035. X    push( complex(&a,log(magnitude(&a))/l10, angle(&a)/l10) );
  2036. X}
  2037. X
  2038. X
  2039. Xf_log()
  2040. X{
  2041. Xstruct value a;
  2042. X    (void) pop(&a);
  2043. X    push( complex(&a,log(magnitude(&a)), angle(&a)) );
  2044. X}
  2045. X
  2046. X
  2047. Xf_besj0()    /* j0(a) = sin(a)/a */
  2048. X{
  2049. Xstruct value a;
  2050. X    a = top_of_stack;
  2051. X    f_sin();
  2052. X    push(&a);
  2053. X    f_div();
  2054. X}
  2055. X
  2056. X
  2057. Xf_besj1()    /* j1(a) = sin(a)/(a**2) - cos(a)/a */
  2058. X{
  2059. Xstruct value a;
  2060. X    a = top_of_stack;
  2061. X    f_sin();
  2062. X    push(&a);
  2063. X    push(&a);
  2064. X    f_mult();
  2065. X    f_div();
  2066. X    push(&a);
  2067. X    f_cos();
  2068. X    push(&a);
  2069. X    f_div();
  2070. X    f_minus();
  2071. X}
  2072. X
  2073. X
  2074. Xf_besy0()    /* y0(a) = -cos(a)/a */
  2075. X{
  2076. Xstruct value a;
  2077. X    a = top_of_stack;
  2078. X    f_cos();
  2079. X    push(&a);
  2080. X    f_div();
  2081. X    f_uminus();
  2082. X}
  2083. X
  2084. X
  2085. Xf_besy1()    /* y1(a) = -cos(a)/(a**2) - sin(a)/a */
  2086. X{
  2087. Xstruct value a;
  2088. X
  2089. X    a = top_of_stack;
  2090. X    f_cos();
  2091. X    push(&a);
  2092. X    push(&a);
  2093. X    f_mult();
  2094. X    f_div();
  2095. X    push(&a);
  2096. X    f_sin();
  2097. X    push(&a);
  2098. X    f_div();
  2099. X    f_plus();
  2100. X    f_uminus();
  2101. X}
  2102. X
  2103. X
  2104. Xf_floor()
  2105. X{
  2106. Xstruct value a;
  2107. X
  2108. X    (void) pop(&a);
  2109. X    switch (a.type) {
  2110. X        case INT:
  2111. X            push( integer(&a,(int)floor((double)a.v.int_val)));            
  2112. X            break;
  2113. X        case CMPLX:
  2114. X            push( complex(&a,floor(a.v.cmplx_val.real),
  2115. X                floor(a.v.cmplx_val.imag)) );
  2116. X    }
  2117. X}
  2118. X
  2119. X
  2120. Xf_ceil()
  2121. X{
  2122. Xstruct value a;
  2123. X
  2124. X    (void) pop(&a);
  2125. X    switch (a.type) {
  2126. X        case INT:
  2127. X            push( integer(&a,(int)ceil((double)a.v.int_val)));            
  2128. X            break;
  2129. X        case CMPLX:
  2130. X            push( complex(&a,ceil(a.v.cmplx_val.real), ceil(a.v.cmplx_val.imag)) );
  2131. X    }
  2132. X}
  2133. X
  2134. X#ifdef GAMMA
  2135. X
  2136. Xf_gamma()
  2137. X{
  2138. Xextern int signgam;
  2139. Xregister double y;
  2140. Xstruct value a;
  2141. X
  2142. X    y = gamma(real(pop(&a)));
  2143. X    if (y > 88.0) {
  2144. X        undefined = TRUE;
  2145. X        push( integer(&a,0) );
  2146. X    }
  2147. X    else
  2148. X        push( complex(&a,signgam * exp(y),0.0) );
  2149. X}
  2150. X
  2151. X#endif /* GAMMA */
  2152. *-*-END-of-standard.c-*-*
  2153. exit
  2154.  
  2155.  
  2156.