home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume40 / gnuplot / part05 < prev    next >
Encoding:
Text File  |  1993-10-21  |  81.5 KB  |  3,068 lines

  1. Newsgroups: comp.sources.misc
  2. From: woo@playfair.stanford.edu ("Alexander Woo")
  3. Subject: v40i017:  gnuplot - interactive function plotting utility, Part05/33
  4. Message-ID: <1993Oct21.144328.1622@sparky.sterling.com>
  5. X-Md4-Signature: d581c782461add0aabde710458b84346
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Thu, 21 Oct 1993 14:43:28 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: woo@playfair.stanford.edu ("Alexander Woo")
  12. Posting-number: Volume 40, Issue 17
  13. Archive-name: gnuplot/part05
  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/command.c.A gnuplot/demo/1.dat
  22. #   gnuplot/term/imagen.trm
  23. # Wrapped by kent@sparky on Wed Oct 20 17:14:39 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 5 (of 33)."'
  27. if test -f 'gnuplot/command.c.A' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'gnuplot/command.c.A'\"
  29. else
  30.   echo shar: Extracting \"'gnuplot/command.c.A'\" \(58930 characters\)
  31.   sed "s/^X//" >'gnuplot/command.c.A' <<'END_OF_FILE'
  32. X#ifndef lint
  33. Xstatic char    *RCSid = "$Id: command.c%v 3.50.1.15 1993/08/21 15:23:42 woo Exp $";
  34. X#endif
  35. X
  36. X
  37. X/* GNUPLOT - command.c */
  38. X/*
  39. X * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  40. X * 
  41. X * Permission to use, copy, and distribute this software and its documentation
  42. X * for any purpose with or without fee is hereby granted, provided that the
  43. X * above copyright notice appear in all copies and that both that copyright
  44. X * notice and this permission notice appear in supporting documentation.
  45. X * 
  46. X * Permission to modify the software is granted, but not the right to distribute
  47. X * the modified code.  Modifications are to be distributed as patches to
  48. X * released version.
  49. X * 
  50. X * This software is provided "as is" without express or implied warranty.
  51. X * 
  52. X * 
  53. X * AUTHORS
  54. X * 
  55. X * Original Software: Thomas Williams,  Colin Kelley.
  56. X * 
  57. X * Gnuplot 2.0 additions: Russell Lang, Dave Kotz, John Campbell.
  58. X * 
  59. X * Gnuplot 3.0 additions: Gershon Elber and many others.
  60. X * 
  61. X * Changes:
  62. X * 
  63. X * Feb 5, 1992    Jack Veenstra    (veenstra@cs.rochester.edu) Added support to
  64. X * filter data values read from a file through a user-defined function before
  65. X * plotting. The keyword "thru" was added to the "plot" command. Example
  66. X * syntax: f(x) = x / 100 plot "test.data" thru f(x) This example divides all
  67. X * the y values by 100 before plotting. The filter function processes the
  68. X * data before any log-scaling occurs. This capability should be generalized
  69. X * to filter x values as well and a similar feature should be added to the
  70. X * "splot" command.
  71. X * 
  72. X * 19 September 1992  Lawrence Crowl  (crowl@cs.orst.edu)
  73. X * Added user-specified bases for log scaling.
  74. X * 
  75. X * There is a mailing list for gnuplot users. Note, however, that the
  76. X * newsgroup 
  77. X *    comp.graphics.gnuplot 
  78. X * is identical to the mailing list (they
  79. X * both carry the same set of messages). We prefer that you read the
  80. X * messages through that newsgroup, to subscribing to the mailing list.
  81. X * (If you can read that newsgroup, and are already on the mailing list,
  82. X * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  83. X * removed from the mailing list.)
  84. X *
  85. X * The address for mailing to list members is
  86. X *       info-gnuplot@dartmouth.edu
  87. X * and for mailing administrative requests is 
  88. X *       info-gnuplot-request@dartmouth.edu
  89. X * The mailing list for bug reports is 
  90. X *       bug-gnuplot@dartmouth.edu
  91. X * The list of those interested in beta-test versions is
  92. X *       info-gnuplot-beta@dartmouth.edu
  93. X */
  94. X
  95. X#include <stdio.h>
  96. X#include <math.h>
  97. X#include <ctype.h>
  98. X
  99. X#ifdef AMIGA_AC_5
  100. X#include <time.h>
  101. Xvoid            sleep();    /* defined later */
  102. X#endif
  103. X
  104. X#ifdef OS2
  105. X#include <setjmp.h>
  106. Xextern jmp_buf env;       /* from plot.c */
  107. X#endif
  108. X
  109. X#if defined(MSDOS) || defined(DOS386)
  110. X#ifdef DJGPP
  111. X#include <dos.h>
  112. X#else
  113. X#include <process.h>
  114. X#endif
  115. X
  116. X#ifdef __ZTC__
  117. X#define P_WAIT 0
  118. X#include <time.h>        /* usleep() */
  119. X#else
  120. X
  121. X#ifdef __TURBOC__
  122. X#ifndef _Windows
  123. X#include <dos.h>        /* sleep() */
  124. X#include <conio.h>
  125. X#include <dir.h>    /* setdisk() */
  126. Xextern unsigned _stklen = 16394;/* increase stack size */
  127. X#endif
  128. X
  129. X#else                /* must be MSC */
  130. X#if !defined(__EMX__) && !defined(DJGPP)
  131. X#ifdef __MSC__
  132. X#include <direct.h>        /* for _chdrive() */
  133. X#endif
  134. X#include <time.h>        /* kludge to provide sleep() */
  135. Xvoid            sleep();    /* defined later */
  136. X#endif                /* !__EMX__ && !DJGPP */
  137. X#endif                /* TURBOC */
  138. X#endif                /* ZTC */
  139. X
  140. X#endif                /* MSDOS */
  141. X
  142. X#ifdef ATARI
  143. X#ifdef __PUREC__
  144. X#include <ext.h>
  145. X#include <tos.h>
  146. X#include <aes.h>
  147. X#else
  148. X#include <osbind.h>
  149. X#include <aesbind.h>
  150. X#endif /* __PUREC__ */
  151. X#endif /* ATARI */
  152. X
  153. X#ifdef AMIGA_SC_6_1
  154. X#include <proto/dos.h>
  155. Xvoid            sleep();
  156. X#endif                /* AMIGA_SC_6_1 */
  157. X
  158. X#include "plot.h"
  159. X#include "setshow.h"
  160. X#ifndef _Windows
  161. X#include "help.h"
  162. X#else
  163. X#define MAXSTR 255
  164. X#endif
  165. X
  166. X#ifndef STDOUT
  167. X#define STDOUT 1
  168. X#endif
  169. X
  170. X#ifndef HELPFILE
  171. X#if defined( MSDOS ) || defined( OS2 ) || defined(DOS386)
  172. X#define HELPFILE "gnuplot.gih"
  173. X#else
  174. X#ifdef AMIGA_SC_6_1
  175. X#define HELPFILE "S:gnuplot.gih"
  176. X#else
  177. X#define HELPFILE "docs/gnuplot.gih"    /* changed by makefile */
  178. X#endif                /* AMIGA_SC_6_1 */
  179. X#endif
  180. X#endif                /* HELPFILE */
  181. X
  182. X#ifdef _Windows
  183. X#include <windows.h>
  184. X#include <setjmp.h>
  185. X#ifdef __MSC__
  186. X#include <malloc.h>
  187. X#else
  188. X#include <alloc.h>
  189. X#include <dir.h>    /* setdisk() */
  190. X#endif
  191. X#include "win/wgnuplib.h"
  192. Xvoid sleep();
  193. Xextern TW textwin;
  194. Xextern jmp_buf FAR env;       /* from plot.c */
  195. Xextern LPSTR winhelpname;
  196. Xextern void screen_dump(void);    /* in term/win.trm */
  197. Xextern int Pause(LPSTR mess); /* in winmain.c */
  198. X#endif
  199. X
  200. X#define inrange(z,min,max) ((min<max) ? ((z>=min)&&(z<=max)) : ((z>=max)&&(z<=min)) )
  201. X
  202. X/*
  203. X * instead of <strings.h>
  204. X */
  205. X
  206. X#ifndef ATARI
  207. X#ifdef _Windows
  208. X#include <string.h>
  209. X#include <stdlib.h>
  210. X#else
  211. X#ifndef AMIGA_SC_6_1
  212. Xextern char    *gets(), *getenv();
  213. X#ifdef sequent
  214. Xextern char    *strcpy(), *strncpy(), *strcat(), *index();
  215. X#else
  216. Xextern char    *strcpy(), *strncpy(), *strcat(), *strchr();
  217. X#endif
  218. Xextern int      strlen();
  219. Xextern int      strcmp();
  220. Xextern double   atof();
  221. X#endif /* !AMIGA_SC_6_1 */
  222. X#endif
  223. X#else
  224. X#ifdef __PUREC__
  225. X/*
  226. X * a substitute for PureC's buggy sscanf.
  227. X * this uses the normal sscanf and fixes the following bugs:
  228. X * - whitespace in format matches whitespace in string, but doesn't
  229. X *   require any. ( "%f , %f" scans "1,2" correctly )
  230. X * - the ignore value feature works (*). this created an address error
  231. X *   in PureC.
  232. X */
  233. X
  234. X#include <stdarg.h>
  235. X#include <string.h>
  236. X
  237. Xint purec_sscanf( const char *string, const char *format, ... )
  238. X{
  239. X  va_list args;
  240. X  int cnt=0;
  241. X  char onefmt[256];
  242. X  char buffer[256];
  243. X  const char *f=format;
  244. X  const char *s=string;
  245. X  char *f2;
  246. X  char ch;
  247. X  int ignore;
  248. X  void *p;
  249. X  int *ip;
  250. X  int pos;
  251. X
  252. X  va_start(args,format);
  253. X  while( *f && *s ) {
  254. X    ch=*f++;
  255. X    if( ch!='%' ) {
  256. X      if(isspace(ch)) {
  257. X        /* match any number of whitespace */
  258. X        while(isspace(*s)) s++;
  259. X      } else {
  260. X        /* match exactly the character ch */
  261. X        if( *s!=ch ) goto finish;
  262. X        s++;
  263. X      }
  264. X    } else {
  265. X      /* we have got a '%' */
  266. X      ch=*f++;
  267. X      if( ch=='%' ) {
  268. X        /* match exactly % */
  269. X        if( *s!=ch ) goto finish;
  270. X        s++;
  271. X      } else {
  272. X        f2=onefmt;
  273. X        *f2++='%';
  274. X        *f2++=ch;
  275. X        ignore=0;
  276. X        if( ch=='*' ) {
  277. X          ignore=1;
  278. X          ch=f2[-1]=*f++;
  279. X        }
  280. X        while( isdigit(ch) ) {
  281. X          ch=*f2++=*f++;
  282. X        }
  283. X        if( ch=='l' || ch=='L' || ch=='h' ) {
  284. X          ch=*f2++=*f++;
  285. X        }
  286. X        switch(ch) {
  287. X          case '[':
  288. X            while( ch && ch!=']' ) {
  289. X              ch=*f2++=*f++;
  290. X            }
  291. X            if( !ch ) goto error;
  292. X            break;
  293. X          case 'e':
  294. X          case 'f':
  295. X          case 'g':
  296. X          case 'd':
  297. X          case 'o':
  298. X          case 'i':
  299. X          case 'u':
  300. X          case 'x':
  301. X          case 'c':
  302. X          case 's':
  303. X          case 'p':
  304. X          case 'n': /* special case handled below */
  305. X            break;
  306. X          default:
  307. X            goto error;
  308. X        }
  309. X        if( ch!='n' ) {
  310. X          strcpy(f2,"%n");
  311. X          if( ignore ) {
  312. X            p=buffer;
  313. X          } else {
  314. X            p=va_arg(args,void *);
  315. X          }
  316. X          switch( sscanf( s, onefmt, p, &pos ) ) {
  317. X            case EOF: goto error;
  318. X            case  0 : goto finish;
  319. X          }
  320. X          if( !ignore ) cnt++;
  321. X          s+=pos;
  322. X        } else {
  323. X          if( !ignore ) {
  324. X            ip=va_arg(args,int *);
  325. X            *ip=(int)(s-string);
  326. X          }
  327. X        }
  328. X      }
  329. X    }
  330. X  }
  331. X
  332. X  if( !*f ) goto finish;
  333. X
  334. Xerror:
  335. X  cnt=EOF;
  336. Xfinish:
  337. X  va_end(args);
  338. X  return cnt;
  339. X}
  340. X
  341. X/* use the substitute now. I know this is dirty trick, but it works. */
  342. X#define sscanf purec_sscanf
  343. X
  344. X#endif /* __PUREC__ */
  345. X#endif /* ATARI */
  346. X
  347. X/*
  348. X * Only reference to contours library.
  349. X */
  350. Xextern struct gnuplot_contours *contour();
  351. X
  352. X#ifdef OS2
  353. X /* emx has getcwd, chdir that can handle drive names */
  354. X#define getcwd _getcwd2
  355. X#define chdir  _chdir2
  356. X#endif /* OS2 */
  357. X
  358. X#if defined(unix) && !defined(hpux)
  359. X#ifdef GETCWD
  360. Xextern char    *getcwd();    /* some Unix's use getcwd */
  361. X#else
  362. Xextern char    *getwd();    /* most Unix's use getwd */
  363. X#endif
  364. X#else
  365. X#ifdef DJGPP
  366. Xextern char    *getwd();    /* DJGPP acts like Unix here */
  367. X#else
  368. Xextern char    *getcwd();    /* Turbo C, MSC, EMX, OS2 and VMS use getcwd */
  369. X#endif
  370. X#endif
  371. X
  372. X#ifdef vms
  373. Xint             vms_vkid;    /* Virtual keyboard id */
  374. X#endif
  375. X    
  376. Xstatic FILE *data_fp=NULL;    /* != means file still open */
  377. Xstatic TBOOLEAN more_data_fp=FALSE;  /* And this explicitly says so. */
  378. X
  379. X#if defined(unix) || defined(PIPES)
  380. Xextern FILE    *popen();
  381. Xstatic TBOOLEAN  pipe_open = FALSE;
  382. X#endif
  383. X
  384. Xextern int      chdir();
  385. X
  386. Xextern double   magnitude(), angle(), real(), imag();
  387. Xextern struct value *const_express(), *pop(), *Gcomplex();
  388. Xextern struct at_type *temp_at(), *perm_at();
  389. Xextern struct udft_entry *add_udf();
  390. Xextern struct udvt_entry *add_udv();
  391. Xextern void     squash_spaces();
  392. Xextern void     lower_case();
  393. X
  394. X/* local functions */
  395. Xstatic enum coord_type adjustlog();
  396. X
  397. Xextern TBOOLEAN  interactive;    /* from plot.c */
  398. X
  399. X/* input data, parsing variables */
  400. Xstruct lexical_unit token[MAX_TOKENS];
  401. Xchar            input_line[MAX_LINE_LEN + 1] = "";
  402. Xint             num_tokens, c_token;
  403. Xint             inline_num = 0;    /* input line number */
  404. X
  405. Xchar            c_dummy_var[MAX_NUM_VAR][MAX_ID_LEN + 1];    /* current dummy vars */
  406. X
  407. X/* the curves/surfaces of the plot */
  408. Xstruct curve_points *first_plot = NULL;
  409. Xstruct surface_points *first_3dplot = NULL;
  410. Xstatic struct udft_entry plot_func;
  411. Xstruct udft_entry *dummy_func;
  412. X
  413. X/* jev -- for passing data thru user-defined function */
  414. Xstatic struct udft_entry ydata_func;
  415. X
  416. X/* support for replot command */
  417. Xchar            replot_line[MAX_LINE_LEN + 1] = "";
  418. Xstatic int      plot_token;    /* start of 'plot' command */
  419. X
  420. X/* If last plot was a 3d one. */
  421. XTBOOLEAN         is_3d_plot = FALSE;
  422. X
  423. Xcom_line()
  424. X{
  425. X   if (read_line(PROMPT))
  426. X       return(1);
  427. X
  428. X    /* So we can flag any new output: if false at time of error, */
  429. X    /* we reprint the command line before printing caret. */
  430. X    /* TRUE for interactive terminals, since the command line is typed. */
  431. X    /* FALSE for non-terminal stdin, so command line is printed anyway. */
  432. X    /* (DFK 11/89) */
  433. X    screen_ok = interactive;
  434. X
  435. X    if (do_line())
  436. X        return(1);
  437. X     else
  438. X        return(0);
  439. X}
  440. X
  441. X
  442. Xdo_line()
  443. X{                /* also used in load_file */
  444. X    if (is_system(input_line[0])) {
  445. X    do_system();
  446. X    (void) fputs("!\n", stderr);
  447. X    return(0);
  448. X    }
  449. X    num_tokens = scanner(input_line);
  450. X    c_token = 0;
  451. X    while (c_token < num_tokens) {
  452. X    if (command())
  453. X           return(1);
  454. X    if (c_token < num_tokens)    /* something after command */
  455. X        if (equals(c_token, ";"))
  456. X        c_token++;
  457. X        else
  458. X        int_error("';' expected", c_token);
  459. X    }
  460. X    return(0);
  461. X}
  462. X
  463. X
  464. X
  465. Xcommand()
  466. X{
  467. X    FILE *fp, *lf_top();
  468. X    int             i;
  469. X    char            sv_file[MAX_LINE_LEN + 1];
  470. X#if defined(__ZTC__)
  471. X    unsigned dummy; /* it's a parameter needed for dos_setdrive */
  472. X#endif
  473. X    /* string holding name of save or load file */
  474. X
  475. X    for (i = 0; i < MAX_NUM_VAR; i++)
  476. X    c_dummy_var[i][0] = '\0';    /* no dummy variables */
  477. X
  478. X    if (is_definition(c_token))
  479. X    define();
  480. X    else if (almost_equals(c_token, "h$elp") || equals(c_token, "?")) {
  481. X    c_token++;
  482. X    do_help();
  483. X    } else if (almost_equals(c_token, "test")) {
  484. X    c_token++;
  485. X    test_term();
  486. X    } else if (almost_equals(c_token, "scr$eendump")) {
  487. X    c_token++;
  488. X#ifdef _Windows
  489. X    screen_dump();
  490. X#else
  491. X    fputs("screendump not implemented\n",stderr);
  492. X#endif
  493. X    } else if (almost_equals(c_token, "pa$use")) {
  494. X    struct value    a;
  495. X    int             stime, text = 0;
  496. X    char            buf[MAX_LINE_LEN + 1];
  497. X
  498. X    c_token++;
  499. X    stime = (int) real(const_express(&a));
  500. X    buf[0]='\0';
  501. X    if (!(END_OF_COMMAND)) {
  502. X        if (!isstring(c_token))
  503. X        int_error("expecting string", c_token);
  504. X        else {
  505. X        quotel_str(buf, c_token);
  506. X#ifdef _Windows
  507. X        if (stime>=0)
  508. X#endif
  509. X#ifdef OS2
  510. X                if( strcmp(term_tbl[term].name, "pm" )!=0 || stime >=0 )
  511. X#endif
  512. X        (void) fprintf(stderr, "%s", buf);
  513. X        text = 1;
  514. X        }
  515. X    }
  516. X    if (stime < 0)
  517. X#ifdef _Windows
  518. X        {
  519. X            if (!Pause(buf))
  520. X                 longjmp(env, TRUE); /* bail out to command line */
  521. X         }
  522. X#else
  523. X#ifdef OS2
  524. X        if( strcmp(term_tbl[term].name, "pm" )==0 && stime < 0 )
  525. X        {
  526. X            int rc ;
  527. X            if( (rc=PM_pause( buf ))==0 ) longjmp(env,TRUE) ;
  528. X            else if( rc==2 ) { 
  529. X        (void) fprintf(stderr, "%s", buf);
  530. X        text = 1;
  531. X                (void) fgets(buf, MAX_LINE_LEN, stdin);
  532. X                }
  533. X        }
  534. X#else
  535. X        (void) fgets(buf, MAX_LINE_LEN, stdin);
  536. X    /* Hold until CR hit. */
  537. X#endif /*OS2*/
  538. X#endif
  539. X#ifdef __ZTC__
  540. X    if (stime > 0)
  541. X        usleep((unsigned long) stime);
  542. X#else
  543. X    if (stime > 0)
  544. X        sleep((unsigned int) stime);
  545. X#endif
  546. X    if (text != 0 && stime >= 0)
  547. X        (void) fprintf(stderr, "\n");
  548. X    c_token++;
  549. X    screen_ok = FALSE;
  550. X    } else if (almost_equals(c_token, "pr$int")) {
  551. X    struct value    a;
  552. X
  553. X    c_token++;
  554. X    (void) const_express(&a);
  555. X    (void) putc('\t', stderr);
  556. X    disp_value(stderr, &a);
  557. X    (void) putc('\n', stderr);
  558. X    screen_ok = FALSE;
  559. X    } else if (almost_equals(c_token, "p$lot")) {
  560. X    plot_token = c_token++;
  561. X#ifdef _Windows
  562. X    SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
  563. X#endif
  564. X    plotrequest();
  565. X#ifdef _Windows
  566. X    SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
  567. X#endif
  568. X    } else if (almost_equals(c_token, "sp$lot")) {
  569. X    plot_token = c_token++;
  570. X#ifdef _Windows
  571. X    SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
  572. X#endif
  573. X    plot3drequest();
  574. X#ifdef _Windows
  575. X    SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
  576. X#endif
  577. X    } else if (almost_equals(c_token, "rep$lot")) {
  578. X    if (replot_line[0] == '\0')
  579. X        int_error("no previous plot", c_token);
  580. X    c_token++;
  581. X#ifdef _Windows
  582. X    SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
  583. X#endif
  584. X    replotrequest();
  585. X#ifdef _Windows
  586. X    SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
  587. X#endif
  588. X    } else if (almost_equals(c_token, "se$t"))
  589. X    set_command();
  590. X    else if (almost_equals(c_token, "sh$ow"))
  591. X    show_command();
  592. X    else if (almost_equals(c_token, "cl$ear")) {
  593. X    if (!term_init) {
  594. X        (*term_tbl[term].init) ();
  595. X        term_init = TRUE;
  596. X    }
  597. X    (*term_tbl[term].graphics) ();
  598. X    (*term_tbl[term].text) ();
  599. X    (void) fflush(outfile);
  600. X    screen_ok = FALSE;
  601. X    c_token++;
  602. X    } else if (almost_equals(c_token, "she$ll")) {
  603. X    do_shell();
  604. X    screen_ok = FALSE;
  605. X    c_token++;
  606. X    } else if (almost_equals(c_token, "sa$ve")) {
  607. X    if (almost_equals(++c_token, "f$unctions")) {
  608. X        if (!isstring(++c_token))
  609. X        int_error("expecting filename", c_token);
  610. X        else {
  611. X        quote_str(sv_file, c_token);
  612. X        save_functions(fopen(sv_file, "w"));
  613. X        }
  614. X    } else if (almost_equals(c_token, "v$ariables")) {
  615. X        if (!isstring(++c_token))
  616. X        int_error("expecting filename", c_token);
  617. X        else {
  618. X        quote_str(sv_file, c_token);
  619. X        save_variables(fopen(sv_file, "w"));
  620. X        }
  621. X    } else if (almost_equals(c_token, "s$et")) {
  622. X        if (!isstring(++c_token))
  623. X        int_error("expecting filename", c_token);
  624. X        else {
  625. X        quote_str(sv_file, c_token);
  626. X        save_set(fopen(sv_file, "w"));
  627. X        }
  628. X    } else if (isstring(c_token)) {
  629. X        quote_str(sv_file, c_token);
  630. X        save_all(fopen(sv_file, "w"));
  631. X    } else {
  632. X        int_error(
  633. X             "filename or keyword 'functions', 'variables', or 'set' expected",
  634. X             c_token);
  635. X    }
  636. X    c_token++;
  637. X    } else if (almost_equals(c_token, "l$oad")) {
  638. X    if (!isstring(++c_token))
  639. X        int_error("expecting filename", c_token);
  640. X    else {
  641. X        quote_str(sv_file, c_token);
  642. X        load_file(fp=fopen(sv_file, "r"), sv_file);
  643. X        /* input_line[] and token[] now destroyed! */
  644. X        c_token = num_tokens = 0;
  645. X    }
  646. X    } else if (almost_equals(c_token,"rer$ead")) {
  647. X            fp = lf_top();
  648. X            if (fp != (FILE *)NULL) rewind(fp);
  649. X            c_token++;
  650. X    } else if (almost_equals(c_token, "cd")) {
  651. X    if (!isstring(++c_token))
  652. X        int_error("expecting directory name", c_token);
  653. X    else {
  654. X        quotel_str(sv_file, c_token);
  655. X#if defined(MSDOS) || defined(_Windows) || defined(ATARI) || defined(DOS386)
  656. X        if (!((strlen(sv_file)==2) && isalpha(sv_file[0]) && (sv_file[1]==':')))
  657. X#endif
  658. X        if (chdir(sv_file)) {
  659. X        int_error("Can't change to this directory", c_token);
  660. X        }
  661. X#if defined(MSDOS) || defined(_Windows) || defined(ATARI) || defined(DOS386)
  662. X        if (isalpha(sv_file[0]) && (sv_file[1]==':')) {
  663. X#ifdef ATARI
  664. X        (void)Dsetdrv(toupper(sv_file[0])-'A');
  665. X#endif
  666. X
  667. X#if defined(__ZTC__)
  668. X      (void)dos_setdrive(toupper(sv_file[0]) - 'A' + 1, &dummy);
  669. X#endif
  670. X
  671. X#if defined(MSDOS) && defined(__EMX__)
  672. X        (void)_chdrive(toupper(sv_file[0]));
  673. X#endif
  674. X#if defined(__MSC__)
  675. X        (void)_chdrive(toupper(sv_file[0])-'A');
  676. X#endif
  677. X#if (defined(MSDOS) || defined(_Windows)) && defined(__TURBOC__)
  678. X        (void) setdisk(toupper(sv_file[0])-'A');
  679. X#endif
  680. X#ifdef DJGPP
  681. X        { union REGS r;
  682. X            r.h.ah = 0x0e;
  683. X            r.x.dx = toupper(sv_file[0])-'A';
  684. X            intdos(&r, &r);
  685. X        }
  686. X#endif
  687. X        }
  688. X#endif
  689. X        c_token++;
  690. X    }
  691. X    } else if (almost_equals(c_token, "pwd")) {
  692. X#if defined(unix) && !defined(hpux)
  693. X#ifdef GETCWD
  694. X    (void) getcwd(sv_file, MAX_ID_LEN);    /* some Unix's use getcwd */
  695. X#else
  696. X    (void) getwd(sv_file);    /* most Unix's use getwd */
  697. X#endif
  698. X#else
  699. X#ifdef __EMX__
  700. X    (void) _getcwd2(sv_file, MAX_ID_LEN);
  701. X#else
  702. X    /* Turbo C and VMS have getcwd() */
  703. X    (void) getcwd(sv_file, MAX_ID_LEN);
  704. X#endif
  705. X#endif
  706. X#ifdef DJGPP
  707. X    { union REGS r;
  708. X        r.h.ah = 0x19;
  709. X        intdos(&r, &r);
  710. X        fprintf(stderr, "%c:", r.h.al + 'a');
  711. X    }
  712. X#endif
  713. X    fprintf(stderr, "%s\n", sv_file);
  714. X    c_token++;
  715. X    } else if (almost_equals(c_token, "ex$it") ||
  716. X           almost_equals(c_token, "q$uit")) {
  717. X    return(1);
  718. X    } else if (!equals(c_token, ";")) {    /* null statement */
  719. X    int_error("invalid command", c_token);
  720. X    }
  721. X    return(0);
  722. X}
  723. X
  724. Xreplotrequest()
  725. X{
  726. X    char            str[MAX_LINE_LEN + 1];
  727. X    if (equals(c_token, "["))
  728. X    int_error("cannot set range with replot", c_token);
  729. X    if (!END_OF_COMMAND) {
  730. X    capture(str, c_token, num_tokens - 1);
  731. X    if ((strlen(str) + strlen(replot_line)) <= MAX_LINE_LEN - 1) {
  732. X        (void) strcat(replot_line, ",");
  733. X        (void) strcat(replot_line, str);
  734. X    } else {
  735. X        int_error("plot line too long with replot arguments", c_token);
  736. X    }
  737. X    }
  738. X    (void) strcpy(input_line, replot_line);
  739. X    screen_ok = FALSE;
  740. X    num_tokens = scanner(input_line);
  741. X    c_token = 1;        /* skip the 'plot' part */
  742. X    is_3d_plot ? plot3drequest() : plotrequest();
  743. X}
  744. X
  745. X
  746. Xplotrequest()
  747. X/*
  748. X * In the parametric case we can say plot [a= -4:4] [-2:2] [-1:1] sin(a),a**2
  749. X * while in the non-parametric case we would say only plot [b= -2:2] [-1:1]
  750. X * sin(b)
  751. X */
  752. X{
  753. X    TBOOLEAN         changed;
  754. X    int             dummy_token = -1;
  755. X
  756. X    is_3d_plot = FALSE;
  757. X
  758. X    if (parametric && strcmp(dummy_var[0], "u") == 0)
  759. X    strcpy(dummy_var[0], "t");
  760. X
  761. X    autoscale_lt = autoscale_t;
  762. X    autoscale_lx = autoscale_x;
  763. X    autoscale_ly = autoscale_y;
  764. X
  765. X    if (!term)            /* unknown */
  766. X    int_error("use 'set term' to set terminal type first", c_token);
  767. X
  768. X    if (equals(c_token, "[")) {
  769. X    c_token++;
  770. X    if (isletter(c_token)) {
  771. X        if (equals(c_token + 1, "=")) {
  772. X        dummy_token = c_token;
  773. X        c_token += 2;
  774. X        } else {
  775. X        /* oops; probably an expression with a variable. */
  776. X        /* Parse it as an xmin expression. */
  777. X        /* used to be: int_error("'=' expected",c_token); */
  778. X        }
  779. X    }
  780. X    changed = parametric ? load_range(&tmin, &tmax) : load_range(&xmin, &xmax);
  781. X    if (!equals(c_token, "]"))
  782. X        int_error("']' expected", c_token);
  783. X    c_token++;
  784. X    if (changed) {
  785. X        if (parametric)
  786. X        autoscale_lt = FALSE;
  787. X        else
  788. X        autoscale_lx = FALSE;
  789. X    }
  790. X    }
  791. X    if (parametric && equals(c_token, "[")) {    /* set optional x ranges */
  792. X    c_token++;
  793. X    changed = load_range(&xmin, &xmax);
  794. X    if (!equals(c_token, "]"))
  795. X        int_error("']' expected", c_token);
  796. X    c_token++;
  797. X    if (changed)
  798. X        if(parametric)
  799. X            autoscale_lt = FALSE;
  800. X        else
  801. X                autoscale_lx = FALSE;
  802. X    }
  803. X    if (equals(c_token, "[")) {    /* set optional y ranges */
  804. X    c_token++;
  805. X    changed = load_range(&ymin, &ymax);
  806. X    if (!equals(c_token, "]"))
  807. X        int_error("']' expected", c_token);
  808. X    c_token++;
  809. X    if (changed)
  810. X        autoscale_ly = FALSE;
  811. X    }
  812. X    /* use the default dummy variable unless changed */
  813. X    if (dummy_token >= 0)
  814. X    copy_str(c_dummy_var[0], dummy_token);
  815. X    else
  816. X    (void) strcpy(c_dummy_var[0], dummy_var[0]);
  817. X
  818. X    eval_plots();
  819. X}
  820. X
  821. Xplot3drequest()
  822. X/*
  823. X * in the parametric case we would say splot [u= -Pi:Pi] [v= 0:2*Pi] [-1:1]
  824. X * [-1:1] [-1:1] sin(v)*cos(u),sin(v)*cos(u),sin(u) in the non-parametric
  825. X * case we would say only splot [x= -2:2] [y= -5:5] sin(x)*cos(y)
  826. X * 
  827. X */
  828. X{
  829. X    TBOOLEAN         changed;
  830. X    int             dummy_token0 = -1, dummy_token1 = -1;
  831. X
  832. X    is_3d_plot = TRUE;
  833. X
  834. X    if (parametric && strcmp(dummy_var[0], "t") == 0) {
  835. X    strcpy(dummy_var[0], "u");
  836. X    strcpy(dummy_var[1], "v");
  837. X    }
  838. X    autoscale_lx = autoscale_x;
  839. X    autoscale_ly = autoscale_y;
  840. X    autoscale_lz = autoscale_z;
  841. X
  842. X    if (!term)            /* unknown */
  843. X    int_error("use 'set term' to set terminal type first", c_token);
  844. X
  845. X    if (equals(c_token, "[")) {
  846. X    c_token++;
  847. X    if (isletter(c_token)) {
  848. X        if (equals(c_token + 1, "=")) {
  849. X        dummy_token0 = c_token;
  850. X        c_token += 2;
  851. X        } else {
  852. X        /* oops; probably an expression with a variable. */
  853. X        /* Parse it as an xmin expression. */
  854. X        /* used to be: int_error("'=' expected",c_token); */
  855. X        }
  856. X    }
  857. X    changed = parametric ? load_range(&umin, &umax) : load_range(&xmin, &xmax);
  858. X    if (!equals(c_token, "]"))
  859. X        int_error("']' expected", c_token);
  860. X    c_token++;
  861. X    if (changed)
  862. X        if(parametric) 
  863. X            autoscale_lu = FALSE;
  864. X        else
  865. X            autoscale_lx = FALSE;
  866. X    }
  867. X    if (equals(c_token, "[")) {
  868. X    c_token++;
  869. X    if (isletter(c_token)) {
  870. X        if (equals(c_token + 1, "=")) {
  871. X        dummy_token1 = c_token;
  872. X        c_token += 2;
  873. X        } else {
  874. X        /* oops; probably an expression with a variable. */
  875. X        /* Parse it as an xmin expression. */
  876. X        /* used to be: int_error("'=' expected",c_token); */
  877. X        }
  878. X    }
  879. X    changed = parametric ? load_range(&vmin, &vmax) : load_range(&ymin, &ymax);
  880. X    if (!equals(c_token, "]"))
  881. X        int_error("']' expected", c_token);
  882. X    c_token++;
  883. X    if (changed)
  884. X        if(parametric) 
  885. X            autoscale_lv = FALSE;
  886. X        else
  887. X            autoscale_ly = FALSE;
  888. X    }
  889. X    if (equals(c_token, "[")) {    /* set optional x (parametric) or z ranges */
  890. X    c_token++;
  891. X    changed = parametric ? load_range(&xmin, &xmax) : load_range(&zmin, &zmax);
  892. X    if (!equals(c_token, "]"))
  893. X        int_error("']' expected", c_token);
  894. X    c_token++;
  895. X    if (changed)
  896. X        if(parametric) 
  897. X            autoscale_lx = FALSE;
  898. X        else
  899. X            autoscale_lz = FALSE;
  900. X    }
  901. X    if (equals(c_token, "[")) {    /* set optional y ranges */
  902. X    c_token++;
  903. X    changed = load_range(&ymin, &ymax);
  904. X    if (!equals(c_token, "]"))
  905. X        int_error("']' expected", c_token);
  906. X    c_token++;
  907. X    if (changed)
  908. X        autoscale_ly = FALSE;
  909. X    }
  910. X    if (equals(c_token, "[")) {    /* set optional z ranges */
  911. X    c_token++;
  912. X    changed = load_range(&zmin, &zmax);
  913. X    if (!equals(c_token, "]"))
  914. X        int_error("']' expected", c_token);
  915. X    c_token++;
  916. X    if (changed)
  917. X        autoscale_lz = FALSE;
  918. X    }
  919. X    /* use the default dummy variable unless changed */
  920. X    if (dummy_token0 >= 0)
  921. X    copy_str(c_dummy_var[0], dummy_token0);
  922. X    else
  923. X    (void) strcpy(c_dummy_var[0], dummy_var[0]);
  924. X
  925. X    if (dummy_token1 >= 0)
  926. X    copy_str(c_dummy_var[1], dummy_token1);
  927. X    else
  928. X    (void) strcpy(c_dummy_var[1], dummy_var[1]);
  929. X
  930. X    eval_3dplots();
  931. X}
  932. X
  933. X
  934. Xdefine()
  935. X{
  936. X    register int    start_token;/* the 1st token in the function definition */
  937. X    register struct udvt_entry *udv;
  938. X    register struct udft_entry *udf;
  939. X
  940. X    if (equals(c_token + 1, "(")) {
  941. X    /* function ! */
  942. X    int             dummy_num = 0;
  943. X    start_token = c_token;
  944. X    do {
  945. X        c_token += 2;    /* skip to the next dummy */
  946. X        copy_str(c_dummy_var[dummy_num++], c_token);
  947. X    } while (equals(c_token + 1, ",") && (dummy_num < MAX_NUM_VAR));
  948. X    if (equals(c_token + 1, ","))
  949. X        int_error("function contains too many parameters", c_token + 2);
  950. X    c_token += 3;        /* skip (, dummy, ) and = */
  951. X    if (END_OF_COMMAND)
  952. X        int_error("function definition expected", c_token);
  953. X    udf = dummy_func = add_udf(start_token);
  954. X    if (udf->at)        /* already a dynamic a.t. there */
  955. X        free((char *) udf->at);    /* so free it first */
  956. X    if ((udf->at = perm_at()) == (struct at_type *) NULL)
  957. X        int_error("not enough memory for function", start_token);
  958. X    m_capture(&(udf->definition), start_token, c_token - 1);
  959. X    } else {
  960. X    /* variable ! */
  961. X    start_token = c_token;
  962. X    c_token += 2;
  963. X    udv = add_udv(start_token);
  964. X    (void) const_express(&(udv->udv_value));
  965. X    udv->udv_undef = FALSE;
  966. X    }
  967. X}
  968. X
  969. Xget_data(this_plot)
  970. X    struct curve_points *this_plot;
  971. X{
  972. X    register int    i, j, l_num, datum;
  973. X    int fcol[5], scol[5], ncol[5], prevmin, col;
  974. X    char  format[MAX_LINE_LEN + 1], data_file[MAX_LINE_LEN + 1],
  975. X          line[MAX_LINE_LEN + 1];
  976. X    /* conversion variables */
  977. X    int n, m, linestat, using;
  978. X    char *s;
  979. X    double val[5], v[5];
  980. X    float fval[5];    /* for use in sscanf */
  981. X
  982. X    /* close forgotten input file (in case of a syntax error) */
  983. X    if( data_fp ) {
  984. X#if defined(unix) || defined(PIPES)
  985. X        if (pipe_open) {
  986. X            (void) pclose(data_fp);
  987. X            pipe_open = FALSE;
  988. X        } else
  989. X#endif /* unix || PIPES */
  990. X        (void) fclose(data_fp);
  991. X        data_fp=NULL;
  992. X    }
  993. X
  994. X    quotel_str(data_file, c_token);
  995. X    this_plot->plot_type = DATA;
  996. X/*    if (parametric)
  997. X        int_error("Parametric data files not yet implemented", NO_CARET);
  998. X*/
  999. X#if defined(unix) || defined(PIPES)
  1000. X    if (*data_file == '<') {
  1001. X        if ((data_fp = popen(data_file + 1, "r")) == (FILE *) NULL)
  1002. X            os_error("cannot create pipe for data", c_token);
  1003. X        else
  1004. X            pipe_open = TRUE;
  1005. X    } else
  1006. X#endif /* unix || PIPES */
  1007. X    if ((data_fp = fopen(data_file, "r")) == (FILE *) NULL)
  1008. X        os_error("can't open data file", c_token);
  1009. X
  1010. X    format[0] = '\0';
  1011. X    for (i=0; i<5; i++)
  1012. X        fcol[i] = i+1;
  1013. X
  1014. X    using = 0;
  1015. X    c_token++;            /* skip data file name */
  1016. X
  1017. X    /* jev -- support for passing data from file thru user function */
  1018. X    if (almost_equals(c_token, "thru$")) {
  1019. X        c_token++;
  1020. X        if (ydata_func.at)
  1021. X            free(ydata_func.at);
  1022. X        dummy_func = &ydata_func;
  1023. X        ydata_func.at = perm_at();
  1024. X    } else {
  1025. X        if (ydata_func.at)
  1026. X            free(ydata_func.at);
  1027. X        ydata_func.at = NULL;
  1028. X    }
  1029. X
  1030. X    if (almost_equals(c_token,"u$sing")) {
  1031. X        using = 1;
  1032. X        c_token++;      /* skip "using" */
  1033. X            
  1034. X        if (!END_OF_COMMAND && !isstring(c_token)) {
  1035. X            struct value a;
  1036. X            for (i=0; i<5; i++)
  1037. X                fcol[i] = -1;
  1038. X            fcol[0] = (int)magnitude(const_express(&a));
  1039. X            for (i=1; equals(c_token,":") && i<5; i++) {
  1040. X                c_token++;      /* skip ":" */
  1041. X                fcol[i] = (int)magnitude(const_express(&a));
  1042. X            }
  1043. X        }
  1044. X
  1045. X        if (!END_OF_COMMAND && isstring(c_token)) {
  1046. X            quotel_str(format, c_token);
  1047. X            c_token++;    /* skip format */
  1048. X        }
  1049. X    }
  1050. X    
  1051. X    /* sort fcol[] into scol[] removing duplicates */
  1052. X    prevmin = 0;
  1053. X    for (i=0; i<5; i++) {
  1054. X        col = 10000;
  1055. X        for (j=0; j<5; j++)
  1056. X            if ((fcol[j]>prevmin) && (fcol[j]<col))
  1057. X                col = fcol[j];
  1058. X        if (col <10000)
  1059. X               prevmin = scol[i] = col;
  1060. X        else
  1061. X            scol[i] = 0;
  1062. X    }
  1063. X    /* normalise fcol[] into ncol[] */
  1064. X    for (i=0; i<5; i++) {
  1065. X        if (fcol[i] > 0)
  1066. X            for (j=0; j<5; j++) {
  1067. X                if (fcol[i] == scol[j])
  1068. X                    ncol[i] = j+1;
  1069. X            }
  1070. X        else if (fcol[i] == 0)
  1071. X            ncol[i] = 0;
  1072. X        else
  1073. X            ncol[i] = -1;
  1074. X    }
  1075. X    /* set col to highest column number */
  1076. X    col = 0;
  1077. X    for (i=0; i<5; i++) 
  1078. X        if (fcol[i]>col) col=fcol[i];
  1079. X
  1080. X    l_num = 0;
  1081. X    datum = 0;
  1082. X    i = 0;
  1083. X    while (fgets(line, MAX_LINE_LEN, data_fp) != (char *) NULL) {
  1084. X        l_num++;
  1085. X        if (is_comment(line[0]))
  1086. X            continue;        /* ignore comments */
  1087. X        if (i >= this_plot->p_max) {
  1088. X            /*
  1089. X             * overflow about to occur. Extend size of points[] array. We
  1090. X             * either double the size, or add 1000 points, whichever is a
  1091. X             * smaller increment. Note i=p_max.
  1092. X             */
  1093. X            cp_extend(this_plot, i + (i < 1000 ? i : 1000));
  1094. X        }
  1095. X        if (!line[1]) {        /* is it blank line ? */
  1096. X            /* break in data, make next point undefined */
  1097. X            this_plot->points[i].type = UNDEFINED;
  1098. X            i++;
  1099. X            continue;
  1100. X        }
  1101. X        if (strlen(format) != 0) {
  1102. X            /* use old sscanf if a format string was given */
  1103. X            m = sscanf(line, format, &fval[0], &fval[1], &fval[2], &fval[3], &fval[4]);
  1104. X            for (n=0; n<5; n++)        /* convert floats from sscanf to double */
  1105. X                val[n] = (double)fval[n];
  1106. X
  1107. X            for (j=0; j<5 && fcol[j]>=0 && fcol[j]-1<m ; j++)
  1108. X                if (fcol[j])
  1109. X                    v[j] = val[fcol[j]-1];
  1110. X                else
  1111. X                    v[j] = datum;    /* using 0:n */
  1112. X        }
  1113. X        else {
  1114. X            /* implement our own sscanf that skips lines with invalid data 
  1115. X             * if a using statement was given */
  1116. X            /* convert the array to its constituents */
  1117. X            for(n=0; n<5; n++)            /* wipe the array */
  1118. X                val[n] = 0.0;
  1119. X            n=0;                        /* n is column number */
  1120. X            m=0;                        /* m is number of values read */
  1121. X            linestat = 1;                /* linestat: 1 OK 2 bad value 0 EOL */
  1122. X            s = line;
  1123. X            while ((linestat == 1) && (n<col)) {
  1124. X                while (isspace(*s)) s++;
  1125. X                if (*s == '\0') {
  1126. X                    linestat = 0;
  1127. X                    break;
  1128. X                }
  1129. X                n++;
  1130. X                if (n == scol[m]) {
  1131. X                    if (isdigit(*s) || *s=='-' || *s=='+' || *s=='.') {
  1132. X                        val[m] = atof(s);
  1133. X                        m++;
  1134. X                    }
  1135. X                    else
  1136. X                        linestat = 2;    /* abort the line non-digit in req loc */
  1137. X                }
  1138. X                while ((!isspace(*s)) && (*s != '\0')) s++;
  1139. X            }
  1140. X
  1141. X            if (using && (linestat == 2))
  1142. X                continue;    /* skip lines where a using pattern is present and not met */
  1143. X
  1144. X            for (j=0; j<5 && ncol[j]>=0 && ncol[j]-1<m ; j++)
  1145. X                if (ncol[j])
  1146. X                    v[j] = val[ncol[j]-1];
  1147. X                else
  1148. X                    v[j] = datum;    /* using 0:n */
  1149. X        }
  1150. X
  1151. X        switch (j) {
  1152. X            case 1: {        /* only one number */
  1153. X                /* x is index, assign number to y */
  1154. X                v[1]=v[0];
  1155. X                v[0]=datum;
  1156. X                /* nobreak */
  1157. X            }
  1158. X            case 2: {        /* x, y */
  1159. X                /* ylow and yhigh are same as y */
  1160. X                datum++;
  1161. X                store2d_point(this_plot, i++, v[0], v[1], v[1], v[1], -1.0);
  1162. X                break;
  1163. X            }
  1164. X            case 3: {        /* x, y, ydelta */
  1165. X                /* ydelta is in the ylow variable */
  1166. X                datum++;
  1167. X                store2d_point(this_plot, i++, v[0], v[1], v[1]-v[2], v[1]+v[2], -1.0);
  1168. X                break;
  1169. X            }
  1170. X            case 4: {        /* x, y, ylow, yhigh */
  1171. X                datum++;
  1172. X                store2d_point(this_plot, i++, v[0], v[1], v[2], v[3], -1.0);
  1173. X                break;
  1174. X            }
  1175. X            case 5: {        /* x, y, ylow, yhigh, width */
  1176. X                datum++;
  1177. X                store2d_point(this_plot, i++, v[0], v[1], v[2], v[3], v[4]);
  1178. X                break;
  1179. X            }
  1180. X            default: {
  1181. X                (void) sprintf(line, "bad data on line %d", l_num);
  1182. X                /* close file before exiting to command level */
  1183. X#if defined(unix) || defined(PIPES)
  1184. X                if (pipe_open) {
  1185. X                    (void) pclose(data_fp);
  1186. X                    pipe_open = FALSE;
  1187. X                } else
  1188. X#endif /* unix || PIPES */
  1189. X                    (void) fclose(data_fp);
  1190. X                data_fp=NULL;
  1191. X                int_error(line, c_token);
  1192. X            }
  1193. X        }
  1194. X    }
  1195. X    this_plot->p_count = i;
  1196. X    cp_extend(this_plot, i);    /* shrink to fit */
  1197. X
  1198. X#if defined(unix) || defined(PIPES)
  1199. X    if (pipe_open) {
  1200. X        (void) pclose(data_fp);
  1201. X        pipe_open = FALSE;
  1202. X    } else
  1203. X#endif /* unix || PIPES */
  1204. X    (void) fclose(data_fp);
  1205. X    data_fp=NULL;
  1206. X}
  1207. X
  1208. X
  1209. X/* called by get_data for each point */
  1210. Xstore2d_point(this_plot, i, x, y, ylow, yhigh, width)
  1211. X    struct curve_points *this_plot;
  1212. X    int             i;        /* point number */
  1213. X    double          x, y;
  1214. X    double          ylow, yhigh;
  1215. X    double          width;
  1216. X{
  1217. X    struct coordinate GPHUGE *cp = &(this_plot->points[i]);
  1218. X
  1219. X    /* the easy part: */
  1220. X    cp->type = INRANGE;
  1221. X    cp->x = x;
  1222. X    cp->y = y;
  1223. X    cp->ylow = ylow;
  1224. X    cp->yhigh = yhigh;
  1225. X    cp->z = width;
  1226. X
  1227. X    /* jev -- pass data values thru user-defined function */
  1228. X    if (ydata_func.at) {
  1229. X    struct value    val;
  1230. X
  1231. X    (void) Gcomplex(&ydata_func.dummy_values[0], y, 0.0);
  1232. X    evaluate_at(ydata_func.at, &val);
  1233. X    cp->y = real(&val);
  1234. X
  1235. X    (void) Gcomplex(&ydata_func.dummy_values[0], ylow, 0.0);
  1236. X    evaluate_at(ydata_func.at, &val);
  1237. X    cp->ylow = real(&val);
  1238. X
  1239. X    (void) Gcomplex(&ydata_func.dummy_values[0], yhigh, 0.0);
  1240. X    evaluate_at(ydata_func.at, &val);
  1241. X    cp->yhigh = real(&val);
  1242. X    }
  1243. X    /* Adjust for log scale. */
  1244. X    if (is_log_x) {
  1245. X        cp->type = adjustlog(cp->type, &(cp->x), log_base_log_x);
  1246. X        (void) adjustlog(cp->type, &(cp->z), log_base_log_z);
  1247. X    }
  1248. X    if (is_log_y) {
  1249. X    cp->type = adjustlog(cp->type, &(cp->y), log_base_log_y);
  1250. X    /* Note ylow,yhigh can't affect cp->type. */
  1251. X    (void) adjustlog(cp->type, &(cp->ylow), log_base_log_y);
  1252. X    (void) adjustlog(cp->type, &(cp->yhigh), log_base_log_y);
  1253. X    }
  1254. X    /* Now adjust the xrange, or declare the point out of range */
  1255. X    /*
  1256. X     * The yrange is handled later, once we know whether to include ylow,
  1257. X     * yhigh in the calculation. See adjust_yrange()
  1258. X     */
  1259. X    if (cp->type == INRANGE)
  1260. X    if (autoscale_lx || inrange(x, xmin, xmax)) {
  1261. X        if (autoscale_lx) {
  1262. X        if (x < xmin)
  1263. X            xmin = x;
  1264. X        if (x > xmax)
  1265. X            xmax = x;
  1266. X        }
  1267. X    } else {
  1268. X        cp->type = OUTRANGE;
  1269. X    }
  1270. X}
  1271. X
  1272. X
  1273. X/*
  1274. X * Adjust for log scale: take the log of the second parameter, in place, if
  1275. X * possible. If not possible, return new type for point; if possible, then
  1276. X * return old type for point.  The log is taken to the base implicit in the
  1277. X * third parameter.
  1278. X */
  1279. Xstatic enum coord_type
  1280. Xadjustlog(type, val, log_base_log)
  1281. X    enum coord_type type;
  1282. X    coordval       *val;
  1283. X    double          log_base_log;
  1284. X{
  1285. X    if (*val < 0.0) {
  1286. X    return (UNDEFINED);
  1287. X    } else if (*val == 0.0) {
  1288. X    *val = -VERYLARGE;
  1289. X    return (OUTRANGE);
  1290. X    } else {
  1291. X    *val = log(*val)/log_base_log;
  1292. X    return (type);
  1293. X    }
  1294. X}
  1295. X
  1296. X
  1297. X/* now adjust the yrange, or declare the point out of range */
  1298. X/* this does all points in a curve */
  1299. Xadjust_yrange(curve)
  1300. X    struct curve_points *curve;
  1301. X{
  1302. X    TBOOLEAN         ebars = (curve->plot_style == ERRORBARS);
  1303. X    int             npoints = curve->p_count;    /* number of points */
  1304. X    coordval        y, ylow, yhigh;    /* one point value */
  1305. X    struct coordinate GPHUGE *cp;    /* one coordinate */
  1306. X    int             i;        /* index into points */
  1307. X
  1308. X    for (i = 0; i < npoints; i++) {
  1309. X    cp = &(curve->points[i]);
  1310. X    if (cp->type == INRANGE) {
  1311. X        y = is_log_y ? pow(base_log_y, cp->y) : cp->y;
  1312. X        if ((autoscale_ly ||
  1313. X        /*
  1314. X         * inrange((is_log_y ? pow(base_log_y, y) : y), ymin, ymax) ||
  1315. X         */
  1316. X         inrange((y), ymin, ymax) ||
  1317. X         polar)) {
  1318. X        if (autoscale_ly) {
  1319. X            if (y < ymin)
  1320. X            ymin = y;
  1321. X            if (y > ymax)
  1322. X            ymax = y;
  1323. X            if (ebars) {
  1324. X            ylow = is_log_y ? pow(base_log_y, cp->ylow) : cp->ylow;
  1325. X            yhigh = is_log_y ? pow(base_log_y, cp->yhigh) : cp->yhigh;
  1326. X            if (ylow < ymin)
  1327. X                ymin = ylow;
  1328. X            if (ylow > ymax)
  1329. X                ymax = ylow;
  1330. X            if (yhigh < ymin)
  1331. X                ymin = yhigh;
  1332. X            if (yhigh > ymax)
  1333. X                ymax = yhigh;
  1334. X            }
  1335. X        }
  1336. X        } else {
  1337. X        cp->type = OUTRANGE;
  1338. X        }
  1339. X    }
  1340. X    }
  1341. X}
  1342. X
  1343. Xgrid_nongrid_data(this_plot)
  1344. Xstruct surface_points *this_plot;
  1345. X{
  1346. X    int i, j, k;
  1347. X    double x, y, z, w, dx, dy, xmin, xmax, ymin, ymax;
  1348. X    struct iso_curve *old_iso_crvs = this_plot->iso_crvs;
  1349. X    struct iso_curve *icrv, *oicrv, *oicrvs;
  1350. X
  1351. X    /* Compute XY bounding box on the original data. */
  1352. X    xmin = xmax = old_iso_crvs->points[0].x;
  1353. X    ymin = ymax = old_iso_crvs->points[0].y;
  1354. X    for (icrv = old_iso_crvs; icrv != NULL; icrv = icrv->next) {
  1355. X    struct coordinate GPHUGE *points = icrv->points;
  1356. X
  1357. X    for (i = 0; i < icrv->p_count; i++, points++) {
  1358. X        if (xmin > points->x)
  1359. X        xmin = points->x;
  1360. X        if (xmax < points->x)
  1361. X        xmax = points->x;
  1362. X        if (ymin > points->y)
  1363. X        ymin = points->y;
  1364. X        if (ymax < points->y)
  1365. X        ymax = points->y;
  1366. X    }
  1367. X    }
  1368. X
  1369. X    dx = (xmax - xmin) / (dgrid3d_row_fineness - 1);
  1370. X    dy = (ymax - ymin) / (dgrid3d_row_fineness - 1);
  1371. X
  1372. X    /* Create the new grid structure, and compute the low pass filtering from
  1373. X     * non grid to grid structure.
  1374. X     */
  1375. X    this_plot->iso_crvs = NULL;
  1376. X    this_plot->num_iso_read = dgrid3d_col_fineness;
  1377. X    this_plot->has_grid_topology = TRUE;
  1378. X    for (i = 0, x = xmin; i < dgrid3d_col_fineness; i++, x += dx) {
  1379. X    struct coordinate GPHUGE *points;
  1380. X
  1381. X    icrv = iso_alloc(dgrid3d_row_fineness + 1);
  1382. X    icrv->p_count = dgrid3d_row_fineness;
  1383. X    icrv->next = this_plot->iso_crvs;
  1384. X    this_plot->iso_crvs = icrv;
  1385. X    points = icrv->points;
  1386. X
  1387. X    for (j = 0, y = ymin; j < dgrid3d_row_fineness; j++, y += dy, points++) {
  1388. X        z = w = 0.0;
  1389. X
  1390. X        for (oicrv = old_iso_crvs; oicrv != NULL; oicrv = oicrv->next) {
  1391. X        struct coordinate GPHUGE *opoints = oicrv->points;
  1392. X        for (k = 0; k < oicrv->p_count; k++, opoints++) {
  1393. X            double dist,
  1394. X               dist_x = fabs( opoints->x - x ),
  1395. X               dist_y = fabs( opoints->y - y );
  1396. X
  1397. X            switch (dgrid3d_norm_value) {
  1398. X            case 1:
  1399. X                dist = dist_x + dist_y;
  1400. X                break;
  1401. X            case 2:
  1402. X                dist = dist_x * dist_x + dist_y * dist_y;
  1403. X                break;
  1404. X            case 4:
  1405. X                dist = dist_x * dist_x + dist_y * dist_y;
  1406. X                dist *= dist;
  1407. X                break;
  1408. X            case 8:
  1409. X                dist = dist_x * dist_x + dist_y * dist_y;
  1410. X                dist *= dist;
  1411. X                dist *= dist;
  1412. X                break;
  1413. X            case 16:
  1414. X                dist = dist_x * dist_x + dist_y * dist_y;
  1415. X                dist *= dist;
  1416. X                dist *= dist;
  1417. X                dist *= dist;
  1418. X                break;
  1419. X            default:
  1420. X                dist = pow( dist_x, dgrid3d_norm_value ) +
  1421. X                   pow( dist_y, dgrid3d_norm_value );
  1422. X                break;
  1423. X            }
  1424. X
  1425. X            /* The weight of this point is inverse proportional
  1426. X             * to the distance.
  1427. X             */
  1428. X            if ( dist == 0.0 )
  1429. X#ifndef AMIGA_SC_6_1
  1430. X            dist = VERYLARGE;
  1431. X#else /* AMIGA_SC_6_1 */
  1432. X            /* Multiplying VERYLARGE by opoints->z below
  1433. X             * might yield Inf (i.e. a number that can't
  1434. X             * be represented on the machine). This will
  1435. X             * result in points->z being set to NaN. It's
  1436. X             * better to have a pretty large number that is
  1437. X             * also on the safe side... The numbers that are
  1438. X             * read by gnuplot are float values anyway, so
  1439. X             * they can't be bigger than FLT_MAX. So setting
  1440. X             * dist to FLT_MAX^2 will make dist pretty large
  1441. X             * with respect to any value that has been read. */
  1442. X            dist = ((double)FLT_MAX)*((double)FLT_MAX);
  1443. X#endif /* AMIGA_SC_6_1 */
  1444. X            else
  1445. X            dist = 1.0 / dist;
  1446. X
  1447. X            z += opoints->z * dist;
  1448. X            w += dist;
  1449. X        }
  1450. X        }
  1451. X
  1452. X        points->x = x;
  1453. X        points->y = y;
  1454. X        points->z = z / w;
  1455. X        points->type = INRANGE;
  1456. X    }
  1457. X    }
  1458. X    
  1459. X    /* Delete the old non grid data. */
  1460. X    for (oicrvs = old_iso_crvs; oicrvs != NULL;) {
  1461. X    oicrv = oicrvs;
  1462. X    oicrvs = oicrvs->next;
  1463. X    iso_free(oicrv);
  1464. X    }
  1465. X}
  1466. X
  1467. Xget_3ddata(this_plot)
  1468. X    struct surface_points *this_plot;
  1469. X{
  1470. X    register int    i, j, l_num, xdatum, ydatum;
  1471. X    float           x, y, z;
  1472. X    char            data_file[MAX_LINE_LEN + 1], line[MAX_LINE_LEN + 1];
  1473. X    char           *float_format = "%f", *float_skip = "%*f";
  1474. X    static TBOOLEAN  only_z = FALSE, using_format = FALSE;
  1475. X    static int      xcol = 1, ycol = 2, zcol = 3, index = -1;
  1476. X    static char     format[MAX_LINE_LEN + 1];
  1477. X    int            pt_in_iso_crv = 0, maxcol, num_col;
  1478. X    enum XYZ_order_type {
  1479. X    XYZ, YXZ, ZXY, XZY, ZYX, YZX, XY, YX
  1480. X    }               xyz_order;
  1481. X    struct iso_curve *this_iso;
  1482. X
  1483. X    /* close forgotten file (in case of a syntax error) */
  1484. X    if (data_fp && !more_data_fp) {
  1485. X#if defined(unix) || defined(PIPES)
  1486. X    if (pipe_open) {
  1487. X        (void) pclose(data_fp);
  1488. X        pipe_open = FALSE;
  1489. X    } else
  1490. X#endif /* unix || PIPES */
  1491. X        (void) fclose(data_fp);
  1492. X        data_fp=NULL;
  1493. X        }
  1494. X
  1495. X    quotel_str(data_file, c_token);
  1496. X    this_plot->plot_type = DATA3D;
  1497. X    this_plot->has_grid_topology = TRUE;
  1498. X    if (!more_data_fp) {
  1499. X#if defined(unix) || defined(PIPES)
  1500. X    if (*data_file == '<') {
  1501. X        if ((data_fp = popen(data_file + 1, "r")) == (FILE *) NULL)
  1502. X        os_error("cannot create pipe; output not changed", c_token);
  1503. X        else
  1504. X        pipe_open = TRUE;
  1505. X    } else
  1506. X#endif /* unix || PIPES */
  1507. X        if ((data_fp = fopen(data_file, "r")) == (FILE *) NULL)
  1508. X        os_error("can't open data file", c_token);
  1509. X
  1510. X    /* Initialize defualt values. */
  1511. X    only_z = FALSE;
  1512. X    using_format = FALSE;
  1513. X    xcol = 1;
  1514. X    ycol = 2;
  1515. X    zcol = 3;
  1516. X    index = -1;
  1517. X    format[0] = '\0';
  1518. X
  1519. X    c_token++;            /* skip data file name */
  1520. X    if (almost_equals(c_token, "i$ndex")) {
  1521. X        struct value a;
  1522. X        c_token++;        /* skip "index" */
  1523. X        index = (int) magnitude(const_express(&a));
  1524. X    }
  1525. X    if (almost_equals(c_token, "u$sing")) {
  1526. X        c_token++;        /* skip "using" */
  1527. X        if (!END_OF_COMMAND && !isstring(c_token)) {
  1528. X        struct value a;
  1529. X        zcol = (int) magnitude(const_express(&a));
  1530. X        only_z = TRUE;
  1531. X        if (equals(c_token, ":")) {
  1532. X            c_token++;    /* skip ":" */
  1533. X            only_z = FALSE;
  1534. X            ycol = zcol;
  1535. X            zcol = (int) magnitude(const_express(&a));
  1536. X            if (equals(c_token, ":")) {
  1537. X            c_token++;    /* skip ":" */
  1538. X            xcol = ycol;
  1539. X            ycol = zcol;
  1540. X            zcol = (int) magnitude(const_express(&a));
  1541. X            } else {
  1542. X            if (mapping3d == MAP3D_CARTESIAN)
  1543. X                int_error("Must specify 1 or 3 columns", c_token);
  1544. X            xcol = ycol;
  1545. X            ycol = zcol;
  1546. X            }
  1547. X        }
  1548. X        if (!only_z)
  1549. X            if ((xcol == ycol) || (ycol == zcol) || (xcol == zcol))
  1550. X            int_error("Columns must be distinct", c_token);
  1551. X        }
  1552. X        if (!END_OF_COMMAND && isstring(c_token)) {
  1553. X        quotel_str(format, c_token);
  1554. X        using_format = TRUE;
  1555. X        c_token++;        /* skip format */
  1556. X        }
  1557. X    } else {
  1558. X        if ( (only_z = !parametric) != FALSE)
  1559. X        zcol = 1;
  1560. X    }
  1561. X    }
  1562. X
  1563. X    switch (mapping3d) {
  1564. X    case MAP3D_CARTESIAN:
  1565. X    maxcol = (xcol > ycol) ? xcol : ycol;
  1566. X    maxcol = (maxcol > zcol) ? maxcol : zcol;
  1567. X    if (!only_z) {        /* Determine ordering of input columns */
  1568. X        if (zcol == maxcol) {
  1569. X        if (xcol < ycol)
  1570. X            xyz_order = XYZ;    /* scanf(x,y,z) */
  1571. X        else
  1572. X            xyz_order = YXZ;    /* scanf(y,x,z) */
  1573. X        } else if (ycol == maxcol) {
  1574. X        if (xcol < zcol)
  1575. X            xyz_order = XZY;    /* scanf(x,z,y) */
  1576. X        else
  1577. X            xyz_order = ZXY;    /* scanf(z,x,y) */
  1578. X        } else {
  1579. X        if (ycol < zcol)
  1580. X            xyz_order = YZX;    /* scanf(y,z,x) */
  1581. X        else
  1582. X            xyz_order = ZYX;    /* scanf(z,y,x) */
  1583. X        }
  1584. X    }
  1585. X    if (strlen(format) == 0) {
  1586. X        if (only_z) {
  1587. X        for (i = 1; i <= zcol; i++)
  1588. X            if (i == zcol)
  1589. X            (void) strcat(format, float_format);
  1590. X            else
  1591. X            (void) strcat(format, float_skip);
  1592. X        } else {
  1593. X        for (i = 1; i <= maxcol; i++)
  1594. X            if ((i == xcol) || (i == ycol) || (i == zcol))
  1595. X            (void) strcat(format, float_format);
  1596. X            else
  1597. X            (void) strcat(format, float_skip);
  1598. X        }
  1599. X    }
  1600. X    break;
  1601. X    case MAP3D_SPHERICAL:
  1602. X    case MAP3D_CYLINDRICAL:
  1603. X    if (only_z)
  1604. X        int_error("Two or three columns for spherical/cylindrical coords.", c_token);
  1605. X    maxcol = (xcol > ycol) ? xcol : ycol;
  1606. X    maxcol = (maxcol > zcol) ? maxcol : zcol;
  1607. X    xyz_order = (xcol < ycol) ? XY : YX;
  1608. X    for (i = 1; i <= maxcol; i++)
  1609. X        if ((i == xcol) || (i == ycol))
  1610. X        (void) strcat(format, float_format);
  1611. X        else
  1612. X        (void) strcat(format, float_skip);
  1613. X    }
  1614. X
  1615. X    l_num = 0;
  1616. X    xdatum = 0;
  1617. X    ydatum = 0;
  1618. X    this_plot->num_iso_read = 0;
  1619. X    this_plot->has_grid_topology = TRUE;
  1620. X    if (this_plot->iso_crvs != NULL) {
  1621. X    struct iso_curve *icrv, *icrvs = this_plot->iso_crvs;
  1622. X
  1623. X    while (icrvs) {
  1624. X        icrv = icrvs;
  1625. X        icrvs = icrvs->next;
  1626. X        iso_free(icrv);
  1627. X    }
  1628. X    this_plot->iso_crvs = NULL;
  1629. X    }
  1630. X    if (!more_data_fp && is_binary_file(data_fp)) {    /* MOD--RKC */
  1631. X#if defined(MSDOS)||defined(ATARI)||defined(OS2)||defined(_Windows)||defined(DOS386)
  1632. X    /* file must be opened with binary flag. the old cr/lf problem again */
  1633. X#ifdef PIPES
  1634. X    if( pipe_open ) {
  1635. X      pclose(data_fp);
  1636. X      data_fp=NULL;
  1637. X      pipe_open=FALSE;
  1638. X      int_error("binary data from pipes is not implemented", NO_CARET);
  1639. X    }
  1640. X#endif
  1641. X    data_fp = freopen(data_file, "rb", data_fp);
  1642. X#endif
  1643. X    xdatum = get_binary_data(this_plot, data_fp, &this_iso);
  1644. X    } else {
  1645. X    int last_line_blank = FALSE;
  1646. X
  1647. X    more_data_fp = FALSE;
  1648. X
  1649. X    this_iso = iso_alloc(samples);
  1650. X
  1651. X    if (index > 0) { /* Skip data meshes until mesh index is reached. */
  1652. X        int i = index;
  1653. X
  1654. X        while (i--) {
  1655. X        while (fgets(line, MAX_LINE_LEN, data_fp) != (char *) NULL) {
  1656. X            l_num++;
  1657. X
  1658. X            if (!line[1]) {    /* is it blank line ? */
  1659. X            if (last_line_blank) /* Two consecutive blanks. */
  1660. X                break;
  1661. X            last_line_blank = TRUE;
  1662. X            }
  1663. X            else
  1664. X            last_line_blank = FALSE;
  1665. X        }
  1666. X        if (feof(data_fp))
  1667. X            int_error("mesh index overflow", NO_CARET);
  1668. X        }
  1669. X    }   /* end of index skip */
  1670. X    
  1671. X    last_line_blank = FALSE;
  1672. X
  1673. X    while (fgets(line, MAX_LINE_LEN, data_fp) != (char *) NULL) {
  1674. X        l_num++;
  1675. X        if (is_comment(line[0]))
  1676. X        continue;    /* ignore comments */
  1677. X        if (!line[1]) {    /* is it blank line ? */
  1678. X        if (last_line_blank) { /* Two consecutive blank lines. */
  1679. X            more_data_fp = TRUE;
  1680. X            break;
  1681. X        }
  1682. X        last_line_blank = TRUE;
  1683. X
  1684. X        if (pt_in_iso_crv == 0) {
  1685. X            if (xdatum == 0)
  1686. X            continue;
  1687. X            pt_in_iso_crv = xdatum;
  1688. X        }
  1689. X        if (xdatum > 0) {
  1690. X            this_iso->p_count = xdatum;
  1691. X            this_iso->next = this_plot->iso_crvs;
  1692. X            this_plot->iso_crvs = this_iso;
  1693. X            this_plot->num_iso_read++;
  1694. X
  1695. X            if (xdatum != pt_in_iso_crv)
  1696. X            this_plot->has_grid_topology = FALSE;
  1697. X
  1698. X            this_iso = iso_alloc(pt_in_iso_crv);
  1699. X            xdatum = 0;
  1700. X            ydatum++;
  1701. X        }
  1702. X        continue;
  1703. X        }
  1704. X        last_line_blank = FALSE;
  1705. X        if (xdatum >= this_iso->p_max) {
  1706. X        /*
  1707. X         * overflow about to occur. Extend size of points[] array. We
  1708. X         * either double the size, or add 1000 points, whichever is a
  1709. X         * smaller increment. Note i=p_max.
  1710. X         */
  1711. X        iso_extend(this_iso,
  1712. X               xdatum + (xdatum < 1000 ? xdatum : 1000));
  1713. X        }
  1714. X        switch (num_col = sscanf(line, format, &x, &y, &z)) {
  1715. X        case 3:        /* All parameter are specified. */
  1716. X        if (!only_z || using_format) {
  1717. X            switch (xyz_order) {
  1718. X            case XYZ:    /* scanf(x,y,z) */
  1719. X            this_iso->points[xdatum].x = x;
  1720. X            this_iso->points[xdatum].y = y;
  1721. X            this_iso->points[xdatum].z = z;
  1722. X            break;
  1723. X            case XZY:    /* scanf(x,z,y) */
  1724. X            this_iso->points[xdatum].x = x;
  1725. X            this_iso->points[xdatum].y = z;
  1726. X            this_iso->points[xdatum].z = y;
  1727. X            break;
  1728. X            case YXZ:    /* scanf(y,x,z) */
  1729. X            this_iso->points[xdatum].x = y;
  1730. X            this_iso->points[xdatum].y = x;
  1731. X            this_iso->points[xdatum].z = z;
  1732. X            break;
  1733. X            case ZXY:    /* scanf(z,x,y) */
  1734. X            this_iso->points[xdatum].x = y;
  1735. X            this_iso->points[xdatum].y = z;
  1736. X            this_iso->points[xdatum].z = x;
  1737. X            break;
  1738. X            case YZX:    /* scanf(y,z,x) */
  1739. X            this_iso->points[xdatum].x = z;
  1740. X            this_iso->points[xdatum].y = x;
  1741. X            this_iso->points[xdatum].z = y;
  1742. X            break;
  1743. X            case ZYX:    /* scanf(z,y,x) */
  1744. X            this_iso->points[xdatum].x = z;
  1745. X            this_iso->points[xdatum].y = y;
  1746. X            this_iso->points[xdatum].z = x;
  1747. X            break;
  1748. X            }
  1749. X            if (xyz_order != XYZ) {
  1750. X            x = this_iso->points[xdatum].x;
  1751. X            y = this_iso->points[xdatum].y;
  1752. X            z = this_iso->points[xdatum].z;
  1753. X            }
  1754. X            if (!parametric)
  1755. X            int_error("Must be in parametric mode.",
  1756. X                  NO_CARET);
  1757. X            break;
  1758. X        }
  1759. X        case 1:        /* only one number on the line */
  1760. X        if (!only_z && !using_format)
  1761. X            int_error("3 columns expected, only 1 found", c_token);
  1762. X        /* assign that number to z */
  1763. X        this_iso->points[xdatum].z = x;
  1764. X        z = x;
  1765. X        this_iso->points[xdatum].x = xdatum;
  1766. X        x = this_iso->points[xdatum].x;
  1767. X        this_iso->points[xdatum].y = ydatum;
  1768. X        y = this_iso->points[xdatum].y;
  1769. X        if (parametric)
  1770. X            int_error("Must be in non parametric mode.",
  1771. X                  NO_CARET);
  1772. X        break;
  1773. X        case 2:
  1774. X        switch (xyz_order) {
  1775. X        case YX:
  1776. X            z = x;    /* Use z as temp */
  1777. X            x = y;
  1778. X            y = z;
  1779. X            break;
  1780. X        default:
  1781. X            break;
  1782. X        }
  1783. X        switch (mapping3d) {
  1784. X        case MAP3D_CARTESIAN:
  1785. X            int_error("2 columns found, 1 or 3 expected",
  1786. X                  c_token);
  1787. X            break;
  1788. X        case MAP3D_SPHERICAL:
  1789. X            if (angles_format == ANGLES_DEGREES) {
  1790. X            x *= DEG2RAD;    /* Convert to radians. */
  1791. X            y *= DEG2RAD;
  1792. X            }
  1793. X            if( num_col == 2) z = 1.0;
  1794. X            this_iso->points[xdatum].x = z*cos(x) * cos(y);
  1795. X            this_iso->points[xdatum].y = z*sin(x) * cos(y);
  1796. X            this_iso->points[xdatum].z = z*sin(y);
  1797. X            break;
  1798. X        case MAP3D_CYLINDRICAL:
  1799. X            if (angles_format == ANGLES_DEGREES)
  1800. X            x *= DEG2RAD;    /* Convert to radians. */
  1801. X            if( num_col == 2) z = 1.0;
  1802. X            this_iso->points[xdatum].x = z*cos(x);
  1803. X            this_iso->points[xdatum].y = z*sin(x);
  1804. X            this_iso->points[xdatum].z = y;
  1805. X            break;
  1806. X        }
  1807. X        x = this_iso->points[xdatum].x;
  1808. X        y = this_iso->points[xdatum].y;
  1809. X        z = this_iso->points[xdatum].z;
  1810. X        break;
  1811. X        default:
  1812. X        (void) sprintf(line, "bad data on line %d", l_num);
  1813. X        int_error(line, c_token);
  1814. X        }
  1815. X
  1816. X        if (is_log_x) {
  1817. X        if (x <= 0.0)
  1818. X            int_error("X value must be above 0 for log scale!",
  1819. X                  NO_CARET);
  1820. X        else
  1821. X            this_iso->points[xdatum].x =
  1822. X            log(this_iso->points[xdatum].x)/log_base_log_x;
  1823. X        }
  1824. X        if (is_log_y) {
  1825. X        if (y <= 0.0)
  1826. X            int_error("Y value must be above 0 for log scale!",
  1827. X                  NO_CARET);
  1828. X        else
  1829. X            this_iso->points[xdatum].y =
  1830. X            log(this_iso->points[xdatum].y)/log_base_log_y;
  1831. X        }
  1832. X        if (is_log_z) {
  1833. X        if (z <= 0.0)
  1834. X            int_error("Z value must be above 0 for log scale!",
  1835. X                  NO_CARET);
  1836. X        else
  1837. X            this_iso->points[xdatum].z =
  1838. X            log(this_iso->points[xdatum].z)/log_base_log_z;
  1839. X        }
  1840. X        if (autoscale_lx) {
  1841. X        if (x < xmin)
  1842. X            xmin = x;
  1843. X        if (x > xmax)
  1844. X            xmax = x;
  1845. X        }
  1846. X        if (autoscale_ly) {
  1847. X        if (y < ymin)
  1848. X            ymin = y;
  1849. X        if (y > ymax)
  1850. X            ymax = y;
  1851. X        }
  1852. X        if (autoscale_lz) {
  1853. X        if (z < zmin)
  1854. X            zmin = z;
  1855. X        if (z > zmax)
  1856. X            zmax = z;
  1857. X        }
  1858. X        xdatum++;    
  1859. X    }  /* end of while loop */
  1860. X
  1861. X    if (xdatum > 0) {
  1862. X        this_plot->num_iso_read++;    /* Update last iso. */
  1863. X        this_iso->p_count = xdatum;
  1864. X
  1865. X        this_iso->next = this_plot->iso_crvs;
  1866. X        this_plot->iso_crvs = this_iso;
  1867. X
  1868. X        if (xdatum != pt_in_iso_crv)
  1869. X        this_plot->has_grid_topology = FALSE;
  1870. X
  1871. X    } else {
  1872. X        iso_free(this_iso);    /* Free last allocation. */
  1873. X    }
  1874. X    }                /* MOD-RKC else of binary */
  1875. X
  1876. X    if (index >= 0) more_data_fp = FALSE; /* Only one data set please. */
  1877. X
  1878. X    if (!more_data_fp) {
  1879. X      if (this_plot->num_iso_read <= 1)
  1880. X      this_plot->has_grid_topology = FALSE;
  1881. X#if defined(unix) || defined(PIPES)
  1882. X      if (pipe_open) {
  1883. X    if (this_plot->has_grid_topology && !hidden3d) {
  1884. X      (void) pclose(data_fp);
  1885. X      pipe_open = FALSE;
  1886. X    }
  1887. X      } else 
  1888. X#endif /* unix || PIPES */
  1889. X      {
  1890. X    (void) fclose(data_fp);  
  1891. X    data_fp = NULL;
  1892. X      }
  1893. X    }
  1894. X
  1895. X    if (dgrid3d) grid_nongrid_data(this_plot);
  1896. X
  1897. X    if (this_plot->num_iso_read <= 1)
  1898. X    this_plot->has_grid_topology = FALSE;
  1899. X    if (this_plot->has_grid_topology && !hidden3d) {
  1900. X    struct iso_curve *new_icrvs = NULL;
  1901. X    int             num_new_iso = this_plot->iso_crvs->p_count, len_new_iso = this_plot->num_iso_read;
  1902. X
  1903. X    /* Now we need to set the other direction (pseudo) isolines. */
  1904. X    for (i = 0; i < num_new_iso; i++) {
  1905. X        struct iso_curve *new_icrv = iso_alloc(len_new_iso);
  1906. X
  1907. X        new_icrv->p_count = len_new_iso;
  1908. X
  1909. X        for (j = 0, this_iso = this_plot->iso_crvs;
  1910. X         this_iso != NULL;
  1911. X         j++, this_iso = this_iso->next) {
  1912. X        new_icrv->points[j].x = this_iso->points[i].x;
  1913. X        new_icrv->points[j].y = this_iso->points[i].y;
  1914. X        new_icrv->points[j].z = this_iso->points[i].z;
  1915. X        }
  1916. X
  1917. X        new_icrv->next = new_icrvs;
  1918. X        new_icrvs = new_icrv;
  1919. X    }
  1920. X
  1921. X    /* Append the new iso curves after the read ones. */
  1922. X    for (this_iso = this_plot->iso_crvs;
  1923. X         this_iso->next != NULL;
  1924. X         this_iso = this_iso->next);
  1925. X        this_iso->next = new_icrvs;
  1926. X    }
  1927. X}
  1928. X
  1929. X/*
  1930. X * print_points: a debugging routine to print out the points of a curve, and
  1931. X * the curve structure. If curve<0, then we print the list of curves.
  1932. X */
  1933. X
  1934. Xstatic char    *plot_type_names[4] =
  1935. X{
  1936. X    "Function", "Data", "3D Function", "3d data"
  1937. X};
  1938. Xstatic char    *plot_style_names[6] =
  1939. X{
  1940. X    "Lines", "Points", "Impulses", "LinesPoints", "Dots", "Errorbars"
  1941. X};
  1942. X
  1943. Xprint_points(curve)
  1944. X    int             curve;    /* which curve to print */
  1945. X{
  1946. X    register struct curve_points *this_plot;
  1947. X    int             i;
  1948. X
  1949. X    if (curve < 0) {
  1950. X    for (this_plot = first_plot, i = 0;
  1951. X         this_plot != NULL;
  1952. X         i++, this_plot = this_plot->next_cp) {
  1953. X        printf("Curve %d:\n", i);
  1954. X        if ((int) this_plot->plot_type >= 0 && (int) (this_plot->plot_type) < 4)
  1955. X        printf("Plot type %d: %s\n", (int) (this_plot->plot_type),
  1956. X               plot_type_names[(int) (this_plot->plot_type)]);
  1957. X        else
  1958. X        printf("Plot type %d: BAD\n", (int) (this_plot->plot_type));
  1959. X        if ((int) this_plot->plot_style >= 0 && (int) (this_plot->plot_style) < 6)
  1960. X        printf("Plot style %d: %s\n", (int) (this_plot->plot_style),
  1961. X               plot_style_names[(int) (this_plot->plot_style)]);
  1962. X        else
  1963. X        printf("Plot style %d: BAD\n", (int) (this_plot->plot_style));
  1964. X        printf("Plot title: '%s'\n", this_plot->title);
  1965. X        printf("Line type %d\n", this_plot->line_type);
  1966. X        printf("Point type %d\n", this_plot->point_type);
  1967. X        printf("max points %d\n", this_plot->p_max);
  1968. X        printf("current points %d\n", this_plot->p_count);
  1969. X        printf("\n");
  1970. X    }
  1971. X    } else {
  1972. X    for (this_plot = first_plot, i = 0;
  1973. X         i < curve && this_plot != NULL;
  1974. X         i++, this_plot = this_plot->next_cp);
  1975. X    if (this_plot == NULL)
  1976. X        printf("Curve %d does not exist; list has %d curves\n", curve, i);
  1977. X    else {
  1978. X        printf("Curve %d, %d points\n", curve, this_plot->p_count);
  1979. X        for (i = 0; i < this_plot->p_count; i++) {
  1980. X        printf("%c x=%g y=%g z=%g ylow=%g yhigh=%g\n",
  1981. X               this_plot->points[i].type == INRANGE ? 'i'
  1982. X               : this_plot->points[i].type == OUTRANGE ? 'o'
  1983. X               : 'u',
  1984. X               this_plot->points[i].x,
  1985. X               this_plot->points[i].y,
  1986. X               this_plot->points[i].z,
  1987. X               this_plot->points[i].ylow,
  1988. X               this_plot->points[i].yhigh);
  1989. X        }
  1990. X        printf("\n");
  1991. X    }
  1992. X    }
  1993. X}
  1994. X
  1995. Xprint_table()
  1996. X{
  1997. X    register struct curve_points *this_plot;
  1998. X    int             i, curve;
  1999. X
  2000. X    for (this_plot = first_plot, curve = 0; this_plot != NULL;
  2001. X     curve++, this_plot = this_plot->next_cp) {
  2002. X    fprintf(outfile, "Curve %d, %d points\n", curve, this_plot->p_count);
  2003. X    for (i = 0; i < this_plot->p_count; i++) {
  2004. X        fprintf(outfile, "%c x=%g y=%g\n",
  2005. X            this_plot->points[i].type == INRANGE ? 'i'
  2006. X            : this_plot->points[i].type == OUTRANGE ? 'o'
  2007. X            : 'u',
  2008. X            this_plot->points[i].x,
  2009. X            this_plot->points[i].y);
  2010. X    }
  2011. X    fprintf(outfile, "\n");
  2012. X    }
  2013. X    fflush(outfile);
  2014. X}
  2015. X
  2016. Xprint_3dtable(pcount)
  2017. Xint pcount;
  2018. X{
  2019. X    register struct surface_points *this_plot;
  2020. X    int             i, curve,surface;
  2021. X    struct iso_curve *icrvs;
  2022. X    struct coordinate GPHUGE *points;
  2023. X
  2024. X    for (surface=0, this_plot=first_3dplot ; surface < pcount; 
  2025. X        this_plot=this_plot->next_sp, surface++){
  2026. X        fprintf(outfile, "\nSurface %d of %d surfaces\n", surface, pcount);
  2027. X        icrvs = this_plot->iso_crvs;
  2028. X        curve = 0;
  2029. X
  2030. X        while(icrvs){
  2031. X            fprintf(outfile, "\nIsoCurve %d, %d points\n", curve, icrvs->p_count);
  2032. X            for(i=0, points = icrvs->points; i < icrvs->p_count; i++){
  2033. X                fprintf(outfile, "%c x=%g y=%g z=%g\n",
  2034. X                points[i].type == INRANGE ? 'i'
  2035. X                : points[i].type == OUTRANGE ? 'o'
  2036. X                : 'u',
  2037. X                points[i].x,
  2038. X                points[i].y,
  2039. X                points[i].z);
  2040. X            }
  2041. X            icrvs = icrvs->next;
  2042. X            curve++;
  2043. X        }
  2044. X    fprintf(outfile, "\n");
  2045. X    }
  2046. X    fflush(outfile);
  2047. X}
  2048. X
  2049. X/*
  2050. X * This parses the plot command after any range specifications. To support
  2051. X * autoscaling on the x axis, we want any data files to define the x range,
  2052. X * then to plot any functions using that range. We thus parse the input
  2053. X * twice, once to pick up the data files, and again to pick up the functions.
  2054. X * Definitions are processed twice, but that won't hurt.
  2055. X */
  2056. Xeval_plots()
  2057. X{
  2058. X    register int    i;
  2059. X    register struct curve_points *this_plot, **tp_ptr;
  2060. X    register int    start_token, end_token;
  2061. X    register int    begin_token;
  2062. X    double          x_min, x_max, y_min, y_max;
  2063. X    register double x, xdiff, temp;
  2064. X    static struct value a;
  2065. X    TBOOLEAN         ltmp, some_data_files = FALSE,is_log_func = FALSE;
  2066. X    int             plot_num, line_num, point_num, xparam = 0;
  2067. X    char           *xtitle;
  2068. X    void            parametric_fixup();
  2069. X
  2070. X    /* Reset first_plot. This is usually done at the end of this function.
  2071. X       If there is an error within this function, the memory is left allocated,
  2072. X       since we cannot call cp_free if the list is incomplete. Making sure that
  2073. X       the list structure is always vaild requires some rewriting */
  2074. X    first_plot=NULL;
  2075. X
  2076. X    if (autoscale_ly) {
  2077. X    ymin = VERYLARGE;
  2078. X    ymax = -VERYLARGE;
  2079. X    } else if (is_log_y && (ymin <= 0.0 || ymax <= 0.0))
  2080. X    int_error("y range must be above 0 for log scale!",
  2081. X          NO_CARET);
  2082. X
  2083. X    tp_ptr = &(first_plot);
  2084. X    plot_num = 0;
  2085. X    line_num = 0;        /* default line type */
  2086. X    point_num = 0;        /* default point type */
  2087. X
  2088. X    xtitle = NULL;
  2089. X
  2090. X    begin_token = c_token;
  2091. X
  2092. X    /*** First Pass: Read through data files ***
  2093. X     * This pass serves to set the xrange and to parse the command, as well
  2094. X     * as filling in every thing except the function data. That is done after
  2095. X     * the xrange is defined.
  2096. X     */
  2097. X    while (TRUE) {
  2098. X    if (END_OF_COMMAND)
  2099. X        int_error("function to plot expected", c_token);
  2100. X
  2101. X    start_token = c_token;
  2102. X
  2103. X    if (is_definition(c_token)) {
  2104. X        define();
  2105. X    } else {
  2106. X        plot_num++;
  2107. X
  2108. X        if (isstring(c_token)) {    /* data file to plot */
  2109. X        if (parametric && xparam)
  2110. X            int_error("previous parametric function not fully specified",
  2111. X                  c_token);
  2112. X
  2113. X        if (!some_data_files && autoscale_lx) {
  2114. X            xmin = VERYLARGE;
  2115. X            xmax = -VERYLARGE;
  2116. X        }
  2117. X        some_data_files = TRUE;
  2118. X
  2119. X        if (*tp_ptr)
  2120. X            this_plot = *tp_ptr;
  2121. X        else {        /* no memory malloc()'d there yet */
  2122. X            this_plot = cp_alloc(MIN_CRV_POINTS);
  2123. X            *tp_ptr = this_plot;
  2124. X        }
  2125. X        this_plot->plot_type = DATA;
  2126. X        this_plot->plot_style = data_style;
  2127. X        end_token = c_token;
  2128. X        get_data(this_plot);    /* this also parses the using option */
  2129. X        } else {        /* function to plot */
  2130. X        if (parametric)    /* working on x parametric function */
  2131. X            xparam = 1 - xparam;
  2132. X        if (*tp_ptr) {
  2133. X            this_plot = *tp_ptr;
  2134. X            cp_extend(this_plot, samples + 1);
  2135. X        } else {    /* no memory malloc()'d there yet */
  2136. X            this_plot = cp_alloc(samples + 1);
  2137. X            *tp_ptr = this_plot;
  2138. X        }
  2139. X        this_plot->plot_type = FUNC;
  2140. X        this_plot->plot_style = func_style;
  2141. X        dummy_func = &plot_func;
  2142. X        plot_func.at = temp_at();
  2143. X        /* ignore it for now */
  2144. X        end_token = c_token - 1;
  2145. X        }
  2146. X
  2147. X        if (almost_equals(c_token, "t$itle")) {
  2148. X        if (parametric) {
  2149. X            if (xparam)
  2150. X            int_error(
  2151. X                     "\"title\" allowed only after parametric function fully specified",
  2152. X                     c_token);
  2153. X            else if (xtitle != NULL)
  2154. X            xtitle[0] = '\0';    /* Remove default title . */
  2155. X        }
  2156. X        c_token++;
  2157. X        if (isstring(c_token)) {
  2158. X            m_quote_capture(&(this_plot->title), c_token, c_token);
  2159. X        } else {
  2160. X            int_error("expecting \"title\" for plot", c_token);
  2161. X        }
  2162. X        c_token++;
  2163. X        } else if (almost_equals(c_token, "not$itle")) {
  2164. X            c_token++;
  2165. X        } else {
  2166. X        m_capture(&(this_plot->title), start_token, end_token);
  2167. X        if (xparam)
  2168. X            xtitle = this_plot->title;
  2169. X        }
  2170. X
  2171. X        this_plot->line_type = line_num;
  2172. X        this_plot->point_type = point_num;
  2173. X
  2174. X        if (almost_equals(c_token, "w$ith")) {
  2175. X        if (parametric && xparam)
  2176. X            int_error("\"with\" allowed only after parametric function fully specified",
  2177. X                  c_token);
  2178. X        this_plot->plot_style = get_style();
  2179. X        }
  2180. X        if (!equals(c_token, ",") && !END_OF_COMMAND) {
  2181. X        struct value    t;
  2182. X        this_plot->line_type = (int) real(const_express(&t)) - 1;
  2183. X        }
  2184. X        if (!equals(c_token, ",") && !END_OF_COMMAND) {
  2185. X        struct value    t;
  2186. X        this_plot->point_type = (int) real(const_express(&t)) - 1;
  2187. X        }
  2188. X        if ((this_plot->plot_style == POINTSTYLE) ||
  2189. X        (this_plot->plot_style == LINESPOINTS) ||
  2190. X        (this_plot->plot_style == ERRORBARS))
  2191. X        if (!xparam)
  2192. X            point_num++;
  2193. X        if (!xparam)
  2194. X        line_num++;
  2195. X
  2196. X        if (this_plot->plot_type == DATA)
  2197. X        /* now that we know the plot style, adjust the yrange */
  2198. X        adjust_yrange(this_plot);
  2199. X
  2200. X        tp_ptr = &(this_plot->next_cp);
  2201. X    }
  2202. X
  2203. X    if (equals(c_token, ","))
  2204. X        c_token++;
  2205. X    else
  2206. X        break;
  2207. X    }
  2208. X
  2209. X    if (parametric && xparam)
  2210. X    int_error("parametric function not fully specified", NO_CARET);
  2211. X
  2212. X    if (parametric) {
  2213. X    /* Swap t and x ranges for duration of these eval_plot computations. */
  2214. X    ltmp = autoscale_lx;
  2215. X    autoscale_lx = autoscale_lt;
  2216. X    autoscale_lt = ltmp;
  2217. X    temp = xmin;
  2218. X    xmin = tmin;
  2219. X    tmin = temp;
  2220. X    temp = xmax;
  2221. X    xmax = tmax;
  2222. X    tmax = temp;
  2223. X    }
  2224. X    /*** Second Pass: Evaluate the functions ***/
  2225. X    /*
  2226. X     * Everything is defined now, except the function data. We expect no
  2227. X     * syntax errors, etc, since the above parsed it all. This makes the code
  2228. X     * below simpler. If autoscale_ly, the yrange may still change.
  2229. X     */
  2230. X    if (fabs(xmax - xmin) < zero)
  2231. END_OF_FILE
  2232.   if test 58930 -ne `wc -c <'gnuplot/command.c.A'`; then
  2233.     echo shar: \"'gnuplot/command.c.A'\" unpacked with wrong size!
  2234.   elif test -f 'gnuplot/command.c.B' ; then
  2235.     echo shar: Combining  \"'gnuplot/command.c'\" \(116680 characters\)
  2236.     cat 'gnuplot/command.c.A' 'gnuplot/command.c.B' > 'gnuplot/command.c'
  2237.     if test 116680 -ne `wc -c <'gnuplot/command.c'`; then
  2238.       echo shar: \"'gnuplot/command.c'\" combined with wrong size!
  2239.     else
  2240.       rm gnuplot/command.c.A gnuplot/command.c.B
  2241.     fi
  2242.   fi
  2243.   # end of 'gnuplot/command.c.A'
  2244. fi
  2245. if test -f 'gnuplot/demo/1.dat' -a "${1}" != "-c" ; then 
  2246.   echo shar: Will not clobber existing file \"'gnuplot/demo/1.dat'\"
  2247. else
  2248.   echo shar: Extracting \"'gnuplot/demo/1.dat'\" \(839 characters\)
  2249.   sed "s/^X//" >'gnuplot/demo/1.dat' <<'END_OF_FILE'
  2250. X#
  2251. X# $Id: 1.dat 3.38.2.6 1992/11/14 02:25:21 woo Exp $
  2252. X#
  2253. X#
  2254. X-20.000000 -3.041676
  2255. X-19.000000 -3.036427
  2256. X-18.000000 -3.030596
  2257. X-17.000000 -3.024081
  2258. X-16.000000 -3.016755
  2259. X-15.000000 -3.008456
  2260. X-14.000000 -2.998978
  2261. X-13.000000 -2.988049
  2262. X-12.000000 -2.975310
  2263. X-11.000000 -2.960273
  2264. X-10.000000 -2.942255
  2265. X-9.000000 -2.920278
  2266. X-8.000000 -2.892883
  2267. X-7.000000 -2.857799
  2268. X-6.000000 -2.811295
  2269. X-5.000000 -2.746802
  2270. X-4.000000 -2.651635
  2271. X-3.000000 -2.498092
  2272. X-2.000000 -2.214297
  2273. X-1.000000 -1.570796
  2274. X0.000000 0.000000
  2275. X1.000000 1.570796
  2276. X2.000000 2.214297
  2277. X3.000000 2.498092
  2278. X4.000000 2.651635
  2279. X5.000000 2.746802
  2280. X6.000000 2.811295
  2281. X7.000000 2.857799
  2282. X8.000000 2.892883
  2283. X9.000000 2.920278
  2284. X10.000000 2.942255
  2285. X11.000000 2.960273
  2286. X12.000000 2.975310
  2287. X13.000000 2.988049
  2288. X14.000000 2.998978
  2289. X15.000000 3.008456
  2290. X16.000000 3.016755
  2291. X17.000000 3.024081
  2292. X18.000000 3.030596
  2293. X19.000000 3.036427
  2294. END_OF_FILE
  2295.   if test 839 -ne `wc -c <'gnuplot/demo/1.dat'`; then
  2296.     echo shar: \"'gnuplot/demo/1.dat'\" unpacked with wrong size!
  2297.   fi
  2298.   # end of 'gnuplot/demo/1.dat'
  2299. fi
  2300. if test -f 'gnuplot/term/imagen.trm' -a "${1}" != "-c" ; then 
  2301.   echo shar: Will not clobber existing file \"'gnuplot/term/imagen.trm'\"
  2302. else
  2303.   echo shar: Extracting \"'gnuplot/term/imagen.trm'\" \(17380 characters\)
  2304.   sed "s/^X//" >'gnuplot/term/imagen.trm' <<'END_OF_FILE'
  2305. X/*
  2306. X * $Id: imagen.trm%v 3.50 1993/07/09 05:35:24 woo Exp $
  2307. X */
  2308. X
  2309. X/* GNUPLOT - imagen.trm */
  2310. X/*
  2311. X * Copyright (C) 1990   
  2312. X *
  2313. X * Permission to use, copy, and distribute this software and its
  2314. X * documentation for any purpose with or without fee is hereby granted, 
  2315. X * provided that the above copyright notice appear in all copies and 
  2316. X * that both that copyright notice and this permission notice appear 
  2317. X * in supporting documentation.
  2318. X *
  2319. X * Permission to modify the software is granted, but not the right to
  2320. X * distribute the modified code.  Modifications are to be distributed 
  2321. X * as patches to released version.
  2322. X *  
  2323. X * This software  is provided "as is" without express or implied warranty.
  2324. X * 
  2325. X * This file is included by ../term.c.
  2326. X *
  2327. X * This terminal driver supports:
  2328. X *   Imagen laser printers
  2329. X *
  2330. X * AUTHORS
  2331. X *   Paul E. McKenney, David Kotz
  2332. X *   Rewritten/extended by:
  2333. X *    Hans Olav Eggestad
  2334. X * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
  2335. X * 
  2336. X */
  2337. X
  2338. X/*
  2339. X * Original for direct Imagen output (but retaining many of the
  2340. X * LaTeX extensions) by Paul E. McKenney, 1989.
  2341. X * Further modified by David Kotz to fit into gnuplot 2.0.
  2342. X * Information Science and Technology Division, SRI International,
  2343. X * 333 Ravenswood Ave, Menlo Park, CA 94025.
  2344. X * Mail to mckenney@sri.com.
  2345. X */
  2346. X
  2347. X#include "impcodes.h"
  2348. X
  2349. X#define IMAGEN_PTS_PER_INCH (300)
  2350. X#define IMAGEN_A4_H  (IMAGEN_PTS_PER_INCH * 83 / 10) /* default is landscape */
  2351. X#define IMAGEN_A4_W  (IMAGEN_PTS_PER_INCH * 116 / 10)
  2352. X
  2353. X#define IMAGEN_XMAX (IMAGEN_PTS_PER_INCH * 11) /* 10.0 inches */
  2354. X#define IMAGEN_YMAX (IMAGEN_PTS_PER_INCH * 78 / 10) /* 7.5 inches */
  2355. X
  2356. Xstatic int IMAGEN_Xmax = IMAGEN_XMAX;  /* width in current orientation */
  2357. Xstatic int IMAGEN_Ymax = IMAGEN_YMAX;
  2358. X
  2359. X#define IMAGEN_FONTSIZE 12
  2360. X#define IMAGEN_FONT "cour"
  2361. X
  2362. X#define IMAGEN_HTIC (20)
  2363. X#define IMAGEN_VTIC (20)
  2364. X#define IMAGEN_VCHAR (IMAGEN_FONTSIZE*5)
  2365. X#define IMAGEN_HCHAR (IMAGEN_VCHAR/2)
  2366. X
  2367. Xunsigned short IMP_gmap[128];
  2368. Xunsigned char IMP_chmap[256];
  2369. X
  2370. Xstatic int IMAGEN_page_h  = IMAGEN_A4_H;
  2371. Xstatic int IMAGEN_page_w = IMAGEN_A4_W;
  2372. Xstatic int IM_win_horiz = 1;
  2373. Xstatic int IM_win_verti = 1;
  2374. Xstatic int IM_plot_nr = 0;
  2375. X
  2376. Xstatic int IMAGEN_fontsize = IMAGEN_FONTSIZE;
  2377. Xstatic int IMAGEN_familytable[36];
  2378. Xstatic int IMAGEN_orgX;        /* absolute-pixel-ORIgin of graph page.    */
  2379. Xstatic int IMAGEN_orgY;
  2380. Xstatic int IMAGEN_orgx;        /* absolute-pixel-ORIgin of current graph. */
  2381. Xstatic int IMAGEN_orgy;
  2382. Xstatic int IMAGEN_posx;        /* current drawing position (lines).    */
  2383. Xstatic int IMAGEN_posy;
  2384. Xstatic int IMAGEN_inplot;
  2385. Xstatic int IMAGEN_xmax = IMAGEN_XMAX;    /* width of graph in pixels.    */
  2386. Xstatic int IMAGEN_ymax = IMAGEN_YMAX;    /* height of graph in pixels.    */
  2387. Xstatic int IMAGEN_winx = IMAGEN_XMAX;    /* width of window in pixels.    */
  2388. Xstatic int IMAGEN_winy = IMAGEN_YMAX;    /* height of window in pixels.    */
  2389. Xstatic int IMAGEN_hchar;    /* Height of CHAR in current font.    */
  2390. Xstatic int IMAGEN_wchar;    /* Width of CHAR in current font.    */
  2391. Xstatic int IMAGEN_blofs;    /* BaseLine OFfSet from bounding box.    */
  2392. Xstatic int IMAGEN_angle = -1;    /* 0 for horizontal text, 1 for vertical */
  2393. Xstatic int IMAGEN_portrait;    /* 0 for landscape */
  2394. Xstatic enum JUSTIFY IMAGEN_justify = LEFT; /* left/center/right */
  2395. X
  2396. Xstatic IMAGEN_seq_pos;        /* position in sequence */
  2397. X
  2398. Xstatic void IMAGEN_putwd();
  2399. Xstatic void IMAGEN_createfamily();
  2400. Xstatic void IMAGEN_setfont();
  2401. Xstatic void IMAGEN_setpos();
  2402. Xvoid IMP_set_draw_pattern();
  2403. Xstatic unsigned char *IMAGEN_cvts();
  2404. X
  2405. X/* char IMPdrpattern[10][10] = { {0}, {30,10,0}, {0}, {10,30,0}, {2,20,0}, 
  2406. X    {20,10,0}, {30,20,10,20,0}, {30,20,4,10,10,10,4,20,0}, {40,20,0}, {30,15,4,15,0}
  2407. X};
  2408. X*/
  2409. X
  2410. Xchar IMPdrpattern[10][10] = { 
  2411. X/* -2 */ {0}, 
  2412. X/* -1 */ {1,8,0}, 
  2413. X/*  0 */ {0}, 
  2414. X/*  1 */ {16,4,0}, 
  2415. X/*  2 */ {3,8,0}, 
  2416. X/*  3 */ {8,8,0}, 
  2417. X/*  4 */ {16,6,3,6,0}, 
  2418. X/*  5 */ {16,6,8,6,0}, 
  2419. X/*  6 */ {16,4,1,4,8,4,1,4,0}, 
  2420. X/*  7 */ {16,4,1,8,1,4,0}
  2421. X};
  2422. X
  2423. XIMAGEN_init()
  2424. X{
  2425. X    register struct termentry *t = &term_tbl[term];
  2426. X
  2427. X    /* char font[10];    */        /* font name */
  2428. X
  2429. X    IMAGEN_posx = IMAGEN_posy = 0;
  2430. X
  2431. X    IMAGEN_orgX = (IMAGEN_page_w - IMAGEN_Xmax) / 2;
  2432. X    IMAGEN_orgY = (IMAGEN_page_h - IMAGEN_Ymax) / 2;
  2433. X
  2434. X    IMAGEN_xmax = IMAGEN_winx = (int)(IMAGEN_Xmax / IM_win_horiz);
  2435. X    IMAGEN_ymax = IMAGEN_winy = (int)(IMAGEN_Ymax / IM_win_verti);
  2436. X
  2437. X    t->xmax = (unsigned int)(IMAGEN_xmax);
  2438. X    t->ymax = (unsigned int)(IMAGEN_ymax);
  2439. X
  2440. X    fputs("@document(language impress, paper a4)", outfile);
  2441. X
  2442. X    if (IMAGEN_portrait) {
  2443. X        putc(imP_SET_ABS_V, outfile);
  2444. X        IMAGEN_putwd(3520);
  2445. X    }
  2446. X    putc(imP_SET_HV_SYSTEM, outfile);
  2447. X    putc(((IMAGEN_portrait?3:0)<<5)|(3<<3)|(IMAGEN_portrait?0:5), outfile);
  2448. X
  2449. X    /* sprintf(font, "cour%02d", IMAGEN_FONTSIZE); */
  2450. X    IMAGEN_mapsinit();
  2451. X    IMAGEN_createmap(1,IMP_gmap);
  2452. X    /* IMAGEN_createfamily(font, IMAGEN_FONTSIZE); */
  2453. X    IMAGEN_setfont(IMAGEN_fontsize);
  2454. X
  2455. X    IMAGEN_text_angle(0);
  2456. X
  2457. X    putc(imP_SET_ABS_H, outfile);
  2458. X    IMAGEN_putwd(0);
  2459. X    putc(imP_SET_ABS_V, outfile);
  2460. X    IMAGEN_putwd(0);
  2461. X
  2462. X    IMAGEN_linetype(-1);
  2463. X}
  2464. X
  2465. XIM_page()
  2466. X{
  2467. X    putc(imP_ENDPAGE, outfile);
  2468. X    putc(imP_PAGE, outfile);
  2469. X}
  2470. X
  2471. XIMAGEN_graphics()
  2472. X{
  2473. X    int tmpx, tmpy;
  2474. X
  2475. X    if ( IM_plot_nr >= ( IM_win_horiz * IM_win_verti )) {
  2476. X    IM_page();
  2477. X    IM_plot_nr = 0;
  2478. X    }
  2479. X    IM_plot_nr++;
  2480. X    tmpx = IMAGEN_orgX + ((IM_plot_nr - 1) % IM_win_horiz) * IMAGEN_winx;
  2481. X    tmpy = IMAGEN_orgY + ((IM_win_verti - 1) - (int)((IM_plot_nr - 1) / IM_win_horiz)) * IMAGEN_winy;
  2482. X    IMAGEN_orgx = tmpx + (int)((IMAGEN_winx - IMAGEN_xmax)/2);
  2483. X    IMAGEN_orgy = tmpy + (int)((IMAGEN_winy - IMAGEN_ymax)/2);
  2484. X}
  2485. X
  2486. XIMAGEN_options()
  2487. X{
  2488. X    extern struct value *const_express();
  2489. X    extern double real();
  2490. X    struct value a;
  2491. X
  2492. X    while (!END_OF_COMMAND) {
  2493. X        if (almost_equals(c_token,"p$ortrait")) {
  2494. X            IMAGEN_portrait=TRUE;
  2495. X            IMAGEN_page_h = IMAGEN_A4_W;
  2496. X            IMAGEN_page_w = IMAGEN_A4_H;
  2497. X            IMAGEN_Xmax = IMAGEN_YMAX;
  2498. X            IMAGEN_Ymax = IMAGEN_XMAX;
  2499. X            c_token++;
  2500. X        }
  2501. X        else if (almost_equals(c_token,"l$andscape")) {
  2502. X            IMAGEN_portrait=FALSE;
  2503. X            c_token++;
  2504. X        } else if (equals(c_token,"[")) { /* windows spesified */
  2505. X            c_token++;
  2506. X            if (IM_plot_nr>1)
  2507. X            if (equals(c_token,"]")) {
  2508. X                IM_page();
  2509. X                c_token++;
  2510. X                continue;
  2511. X            }
  2512. X            if (END_OF_COMMAND) {
  2513. X                    int_error("no. windows: [horizontal,vertical] expected",c_token);
  2514. X            } else if (!equals(c_token,","))  {
  2515. X                IM_win_horiz = (int)real(const_express(&a));
  2516. X            }    
  2517. X            if (!equals(c_token,","))
  2518. X                int_error("',' expected",c_token);
  2519. X            c_token++;
  2520. X            if (!equals(c_token,"]")) {
  2521. X                IM_win_verti = (int)real(const_express(&a));
  2522. X             }
  2523. X            if (!equals(c_token,"]"))
  2524. X                  int_error("expecting ']'",c_token);
  2525. X            c_token++;
  2526. X        } else {
  2527. X            /* We have font size specified */
  2528. X            IMAGEN_fontsize = (int)real(const_express(&a));
  2529. X            if ( IMAGEN_fontsize < 8 ) 
  2530. X                IMAGEN_fontsize = 8;
  2531. X            if ( IMAGEN_fontsize > 15 ) 
  2532. X                IMAGEN_fontsize = 15;
  2533. X        }
  2534. X    }
  2535. X    sprintf(term_options,"%d %s [%1d,%1d]",IMAGEN_fontsize,(IMAGEN_portrait)?"portrait":"landscape",IM_win_horiz,IM_win_verti);
  2536. X}
  2537. X
  2538. X
  2539. XIMAGEN_text()
  2540. X{
  2541. X}
  2542. X
  2543. XIMAGEN_scale(xs, ys)
  2544. X    double xs, ys;            /* scaling factors */
  2545. X{
  2546. X    register struct termentry *t = &term_tbl[term];
  2547. X
  2548. X    /* we change the table for use in graphics.c and IMAGEN_graphics */
  2549. X    t->xmax = (unsigned int)(xs * IMAGEN_winx);
  2550. X    IMAGEN_xmax = t->xmax ;
  2551. X    t->ymax = (unsigned int)(ys * IMAGEN_winy);
  2552. X    IMAGEN_ymax = t->ymax ;
  2553. X
  2554. X    return TRUE ;
  2555. X}
  2556. X
  2557. X#define DRAW_PATTERNS 6
  2558. X
  2559. X
  2560. XIMAGEN_linetype(lt)
  2561. Xint lt;
  2562. X{
  2563. X    static int lastlinetype = -10;
  2564. X    int pen;
  2565. X
  2566. X/* -2: axis
  2567. X   -1: border
  2568. X    0: arrow
  2569. X    1-7: graph
  2570. X*/
  2571. X    if (lt == -2) {
  2572. X        pen = 4;
  2573. X    } else {
  2574. X        pen = (int) (lt/8)*2;
  2575. X        if ( pen <= 0 ) pen = 1;
  2576. X    }
  2577. X    lt  = (lt % 8) +2;
  2578. X
  2579. X    if (lastlinetype == lt)
  2580. X     return;
  2581. X
  2582. X    lastlinetype = lt;    
  2583. X
  2584. X    putc(imP_SET_PEN, outfile);
  2585. X    putc(pen, outfile);
  2586. X    IMP_set_draw_pattern(lt,pen);
  2587. X}
  2588. X
  2589. X
  2590. XIMAGEN_move(x,y)
  2591. X    unsigned int x,y;
  2592. X{
  2593. X    IMAGEN_posx = x;
  2594. X    IMAGEN_posy = y;
  2595. X}
  2596. X
  2597. XIMAGEN_vector(ux,uy)
  2598. X    unsigned int ux,uy;
  2599. X{
  2600. X    /* Create path. */
  2601. X
  2602. X    putc(imP_CREATE_PATH, outfile);
  2603. X    IMAGEN_putwd(2);
  2604. X    IMAGEN_putwd(IMAGEN_posx + IMAGEN_orgx);
  2605. X    IMAGEN_putwd(IMAGEN_posy + IMAGEN_orgy);
  2606. X    IMAGEN_putwd(ux + IMAGEN_orgx);
  2607. X    IMAGEN_putwd(uy + IMAGEN_orgy);
  2608. X
  2609. X    /* Draw path with black pen. */
  2610. X
  2611. X    putc(imP_DRAW_PATH, outfile);
  2612. X    putc(15, outfile);
  2613. X
  2614. X    /* Set current position to end of line. */
  2615. X
  2616. X    IMAGEN_move(ux, uy);
  2617. X}
  2618. X
  2619. Xstatic void
  2620. XIMAGEN_setpos(ux, uy)
  2621. X    int ux,uy;
  2622. X{
  2623. X    /* Set x and y position (for text), also set beginning-of-line. */
  2624. X
  2625. X    putc(imP_SET_ABS_H, outfile);
  2626. X    IMAGEN_putwd(ux + IMAGEN_orgx);
  2627. X    putc(imP_SET_ABS_V, outfile);
  2628. X    IMAGEN_putwd(uy + IMAGEN_orgy);
  2629. X    putc(imP_SET_BOL, outfile);
  2630. X    if (IMAGEN_angle == 1)
  2631. X     IMAGEN_putwd(uy + IMAGEN_orgx); /* vertical */
  2632. X    else
  2633. X     IMAGEN_putwd(ux + IMAGEN_orgx); /* horizontal */
  2634. X}
  2635. X
  2636. XIMAGEN_text_angle(angle)
  2637. X    int angle;
  2638. X{
  2639. X    if (IMAGEN_angle != angle) {
  2640. X       IMAGEN_angle = angle;    /* record for later use */
  2641. X       putc(imP_SET_ADV_DIRS, outfile);
  2642. X       putc(angle == 0 ? 0 : 7, outfile); /* 0=>horiz : 7=>vert */
  2643. X    }
  2644. X
  2645. X    return(TRUE);
  2646. X}
  2647. X
  2648. XIMAGEN_justify_text(mode)
  2649. X    enum JUSTIFY mode;
  2650. X{
  2651. X    IMAGEN_justify = mode;
  2652. X    return(TRUE);
  2653. X}
  2654. X
  2655. Xstatic unsigned char *
  2656. XIMAGEN_cvts(str, width, height)
  2657. X    unsigned char        *str;
  2658. X    int        *width;
  2659. X    int        *height;
  2660. X{
  2661. X    unsigned char        *cp1;
  2662. X    unsigned char        *cp2;
  2663. X    static unsigned char    *buf = NULL;
  2664. X    int        h;
  2665. X    int        maxw;
  2666. X    int        w;
  2667. X
  2668. X    /* Free up old buffer, if there is one, get a new one.  Since    */
  2669. X    /* all transformations shorten the string, get a buffer that is    */
  2670. X    /* the same size as the input string.                */
  2671. X
  2672. X    if (buf != NULL)
  2673. X     (void) free(buf);
  2674. X    buf = (unsigned char *) alloc(strlen(str) + 1, "converted label string");
  2675. X
  2676. X    /* Do the transformations. */
  2677. X
  2678. X    cp1 = str;
  2679. X    cp2 = buf;
  2680. X    h = 1;
  2681. X    maxw = 0;
  2682. X    w = 0;
  2683. X    while (strlen(cp1) > 0) {
  2684. X       switch (*cp1) {
  2685. X          case ' ' :        /* Space character. */
  2686. X            *cp2++ = imP_SP;
  2687. X            w++;
  2688. X            break;
  2689. X            
  2690. X            case  '\\' :    /* Escape sequence. */
  2691. X             if (*++cp1 == '\\') {
  2692. X                /* Begin new line. */
  2693. X                h++;
  2694. X                if (w > maxw)
  2695. X                  maxw = w;
  2696. X                w = 0;
  2697. X                *cp2++ = '\n';
  2698. X                /* *cp2++ = imP_CRLF; */
  2699. X                break;
  2700. X             }
  2701. X            
  2702. X            /* Fall through to just copy next char out.    */
  2703. X            
  2704. X            default :
  2705. X             /* *cp2++ = *cp1; */
  2706. X             *cp2++ = IMP_chmap[*cp1];
  2707. X            w++;
  2708. X            break;
  2709. X        }
  2710. X       cp1++;
  2711. X    }
  2712. X    
  2713. X    *cp2++ = '\n';
  2714. X    *cp2 = '\0';
  2715. X    if (w > maxw)
  2716. X     maxw = w;
  2717. X    
  2718. X    if (height != NULL)
  2719. X     *height = IMAGEN_angle ?
  2720. X       IMAGEN_wchar * maxw :
  2721. X        IMAGEN_hchar * h;
  2722. X    if (width != NULL)
  2723. X     *width = IMAGEN_angle ?
  2724. X       IMAGEN_hchar * h :
  2725. X        IMAGEN_wchar * maxw;
  2726. X    return (buf);
  2727. X}
  2728. X
  2729. XIMAGEN_put_text(x, y, str)
  2730. X    int x,y;                /* reference point of string */
  2731. X    unsigned char str[];            /* the text */
  2732. X{
  2733. X    unsigned char *cvstr, *p; 
  2734. X    int height;
  2735. X    int width;
  2736. X    int sx, sy;
  2737. X    
  2738. X    cvstr = IMAGEN_cvts(str, &width, &height);
  2739. X
  2740. X    if (IMAGEN_angle) {        /* vertical */
  2741. X    /* x += IMAGEN_hchar; */
  2742. X       x -= width/2 - IMAGEN_hchar;
  2743. X      /* y -= height/2; */
  2744. X    } else                /* horizontal */
  2745. X     y += height/2 - IMAGEN_hchar;
  2746. X
  2747. X#ifdef sequent
  2748. X    while ( p=(unsigned char *)index(cvstr,'\n' )) {
  2749. X#else
  2750. X    while ( p=(unsigned char *)strchr(cvstr,'\n' )) {
  2751. X#endif
  2752. X    *p = '\0';
  2753. X        sx = x;
  2754. X        sy = y;
  2755. X        if ( IMAGEN_angle )
  2756. X        sx = x - IMAGEN_blofs;
  2757. X        else
  2758. X        sy = y + IMAGEN_blofs;
  2759. X    
  2760. X        width = strlen(cvstr)*IMAGEN_wchar;
  2761. X    
  2762. X        switch (IMAGEN_justify) {
  2763. X           case LEFT: 
  2764. X            break;
  2765. X           case CENTRE: 
  2766. X            if ( IMAGEN_angle ) {
  2767. X                sy = y - width/2;
  2768. X            } else {
  2769. X                sx = x - width/2;
  2770. X            }
  2771. X            break;
  2772. X            /*x -= width/2; break; */
  2773. X           case RIGHT: 
  2774. X            if ( IMAGEN_angle ) {
  2775. X                sy = y - width;
  2776. X            } else {
  2777. X                sx = x - width;
  2778. X            }
  2779. X            break;
  2780. X            /* x -= width; break; */
  2781. X        }
  2782. X
  2783. X        IMAGEN_setpos(sx, sy);
  2784. X        fputs((char*) cvstr, outfile);
  2785. X    cvstr = ++p;
  2786. X    if (IMAGEN_angle) {     /* vertical */
  2787. X        x += IMAGEN_hchar;
  2788. X    } else {
  2789. X        y -= IMAGEN_hchar;
  2790. X    }
  2791. X
  2792. X    }
  2793. X}
  2794. X
  2795. XIMAGEN_reset()
  2796. X{
  2797. X    putc(imP_EOF, outfile);
  2798. X}
  2799. X
  2800. Xstatic void
  2801. XIMAGEN_putwd(w)
  2802. X{
  2803. X    putc(w>>8, outfile);
  2804. X    putc(w, outfile);
  2805. X}
  2806. X
  2807. Xstatic void
  2808. XIMAGEN_createfamily(c, sz)
  2809. X    char        *c;
  2810. X    int        sz;
  2811. X{
  2812. X
  2813. X    putc(imP_CREATE_FAMILY_TABLE, outfile);
  2814. X    putc(sz, outfile);
  2815. X    putc(1, outfile);
  2816. X    putc(1, outfile);
  2817. X    /* putc(0, outfile); */
  2818. X    fputs(c, outfile);
  2819. X    putc(0, outfile);
  2820. X}
  2821. X
  2822. Xstatic void
  2823. XIMAGEN_setfont(sz) 
  2824. X    int sz;
  2825. X{
  2826. X    char font[20];
  2827. X
  2828. X    if ( ! IMAGEN_familytable[sz] ) {
  2829. X    sprintf(font,"%s%02d",IMAGEN_FONT,sz);
  2830. X    IMAGEN_createfamily(font, sz);
  2831. X        IMAGEN_familytable[sz] = sz;
  2832. X    }
  2833. X    IMAGEN_hchar = sz * 5;
  2834. X    IMAGEN_wchar = IMAGEN_hchar / 2;
  2835. X    IMAGEN_blofs = IMAGEN_hchar / 3;
  2836. X    term_tbl[term].v_char = IMAGEN_hchar;
  2837. X    term_tbl[term].h_char = IMAGEN_wchar;
  2838. X    putc(imP_SET_FAMILY, outfile);
  2839. X    putc(sz, outfile);
  2840. X    putc(imP_SET_SP, outfile);
  2841. X    IMAGEN_putwd(IMAGEN_wchar);
  2842. X    putc(imP_SET_IL, outfile);
  2843. X    IMAGEN_putwd(IMAGEN_hchar);
  2844. X}
  2845. X
  2846. Xvoid
  2847. XIMP_set_draw_pattern(pattern,sz)
  2848. Xint sz, pattern;
  2849. X{
  2850. X    int i;
  2851. X    putc(imP_SET_DRAW_PATTERN, outfile);
  2852. X    putc(0,outfile);
  2853. X    putc(imP_SET_DRAW_PATTERN, outfile);
  2854. X    /* if ( strlen(IMPdrpattern[pattern]) == 1 ) {
  2855. X        putc(type,outfile);
  2856. X        return;
  2857. X    } */ 
  2858. X    putc(strlen(IMPdrpattern[pattern]),outfile);
  2859. X    for ( i=0;i<strlen(IMPdrpattern[pattern]);i++) {
  2860. X        IMAGEN_putwd(IMPdrpattern[pattern][i]*sz);
  2861. X    }
  2862. X}
  2863. X
  2864. X
  2865. XIMAGEN_mapsinit()
  2866. X{
  2867. X
  2868. X    register int i;
  2869. X
  2870. X    for ( i=32;i<127;i++) {
  2871. X        IMP_gmap[i] = i;
  2872. X    }
  2873. X    IMP_gmap[1] = 225;
  2874. X    IMP_gmap[2]  = 233;
  2875. X    IMP_gmap[3] = 61736;
  2876. X    IMP_gmap[4] = 241;
  2877. X    IMP_gmap[5]  = 249;
  2878. X    IMP_gmap[6] = 61864;
  2879. X    IMP_gmap[7] = 162;
  2880. X    IMP_gmap[8] = 163;
  2881. X    IMP_gmap[9] = 164;
  2882. X    IMP_gmap[10] = 165;
  2883. X    IMP_gmap[11] = 167;
  2884. X    IMP_gmap[12] = 171;
  2885. X    IMP_gmap[13] = 182;
  2886. X    IMP_gmap[14] = 61346;
  2887. X    IMP_gmap[15] = 191;
  2888. X    IMP_gmap[16] = 187;
  2889. X    IMP_gmap[17] = 188;
  2890. X    IMP_gmap[18] = 189;
  2891. X    IMP_gmap[19] = 190;
  2892. X    IMP_gmap[20] = 210;
  2893. X    IMP_gmap[21] = 211;
  2894. X    IMP_gmap[22] = 251;
  2895. X    IMP_gmap[23] = 61232;
  2896. X    IMP_gmap[24] = 212;
  2897. X    IMP_gmap[25] = 137;
  2898. X    IMP_gmap[26] = 176;
  2899. X    IMP_gmap[27] = 161;
  2900. X    IMP_gmap[28] = 139;
  2901. X    IMP_gmap[29] = 133;
  2902. X    IMP_gmap[30] = 140;
  2903. X    IMP_gmap[31] = 61249;
  2904. X    IMP_gmap[32] = 8738;
  2905. X    IMP_gmap[34] = 186;
  2906. X    IMP_gmap[36] = 164;
  2907. X    IMP_gmap[39] = 185;
  2908. X    IMP_gmap[127] = 61286;
  2909. X
  2910. X    /* for (i=1;i<127;i++) fprintf(stderr,"%d -> %d\n",i,IMP_gmap[i]); */
  2911. X
  2912. X    for ( i=32;i<=127;i++) {
  2913. X        IMP_chmap [i] = i;
  2914. X    }
  2915. X    for ( i=128;i<=255;i++) {
  2916. X        IMP_chmap [i] = 128; /* first map all non printable chars to SPACE */
  2917. X    }
  2918. X
  2919. X    IMP_chmap [161] = 27;
  2920. X    IMP_chmap [162] = 7;
  2921. X    IMP_chmap [163] = 8;
  2922. X    IMP_chmap [164] = 120;
  2923. X    IMP_chmap [165] = 10;
  2924. X    IMP_chmap [166] = 124;
  2925. X    IMP_chmap [167] = 11;
  2926. X    IMP_chmap [168] = 25;
  2927. X    IMP_chmap [169] = 21;
  2928. X    IMP_chmap [170] = 45;
  2929. X    IMP_chmap [171] = 12;
  2930. X    IMP_chmap [172] = 83;
  2931. X    IMP_chmap [173] = 45;
  2932. X    IMP_chmap [174] = 20;
  2933. X    IMP_chmap [175] = 126;
  2934. X    IMP_chmap [176] = 26;
  2935. X    IMP_chmap [177] = 12;
  2936. X    IMP_chmap [178] = 1;
  2937. X    IMP_chmap [179] = 2;
  2938. X    IMP_chmap [180] = 29;
  2939. X    IMP_chmap [181] = 52;
  2940. X    IMP_chmap [182] = 13;
  2941. X    IMP_chmap [183] = 5;
  2942. X    IMP_chmap [184] = 28;
  2943. X    IMP_chmap [185] = 3;
  2944. X    IMP_chmap [186] = 45;
  2945. X    IMP_chmap [187] = 16;
  2946. X    IMP_chmap [188] = 17;
  2947. X    IMP_chmap [189] = 18;
  2948. X    IMP_chmap [190] = 19;
  2949. X    IMP_chmap [191] = 15;
  2950. X    IMP_chmap [192] = 65;
  2951. X    IMP_chmap [193] = 65;
  2952. X    IMP_chmap [194] = 65;
  2953. X    IMP_chmap [195] = 65;
  2954. X    IMP_chmap [196] = 65;
  2955. X    IMP_chmap [197] = 3;
  2956. X    IMP_chmap [198] = 1;
  2957. X    IMP_chmap [199] = 67;
  2958. X    IMP_chmap [200] = 69;
  2959. X    IMP_chmap [201] = 69;
  2960. X    IMP_chmap [202] = 69;
  2961. X    IMP_chmap [203] = 69;
  2962. X    IMP_chmap [204] = 73;
  2963. X    IMP_chmap [205] = 73;
  2964. X    IMP_chmap [206] = 73;
  2965. X    IMP_chmap [207] = 73;
  2966. X    IMP_chmap [208] = 68;
  2967. X    IMP_chmap [209] = 78;
  2968. X    IMP_chmap [210] = 79;
  2969. X    IMP_chmap [211] = 79;
  2970. X    IMP_chmap [212] = 79;
  2971. X    IMP_chmap [213] = 79;
  2972. X    IMP_chmap [214] = 79;
  2973. X    IMP_chmap [215] = 13;
  2974. X    IMP_chmap [216] = 2;
  2975. X    IMP_chmap [217] = 85;
  2976. X    IMP_chmap [218] = 85;
  2977. X    IMP_chmap [219] = 85;
  2978. X    IMP_chmap [220] = 85;
  2979. X    IMP_chmap [221] = 89;
  2980. X    IMP_chmap [222] = 32;
  2981. X    IMP_chmap [223] = 22;
  2982. X    IMP_chmap [224] = 97;
  2983. X    IMP_chmap [225] = 97;
  2984. X    IMP_chmap [226] = 97;
  2985. X    IMP_chmap [227] = 97;
  2986. X    IMP_chmap [228] = 97;
  2987. X    IMP_chmap [229] = 6;
  2988. X    IMP_chmap [230] = 4;
  2989. X    IMP_chmap [231] = 99;
  2990. X    IMP_chmap [232] = 101;
  2991. X    IMP_chmap [233] = 101;
  2992. X    IMP_chmap [234] = 101;
  2993. X    IMP_chmap [235] = 101;
  2994. X    IMP_chmap [236] = 105;
  2995. X    IMP_chmap [237] = 105;
  2996. X    IMP_chmap [238] = 105;
  2997. X    IMP_chmap [239] = 105;
  2998. X    IMP_chmap [240] = 100;
  2999. X    IMP_chmap [241] = 110;
  3000. X    IMP_chmap [242] = 111;
  3001. X    IMP_chmap [243] = 111;
  3002. X    IMP_chmap [244] = 111;
  3003. X    IMP_chmap [245] = 111;
  3004. X    IMP_chmap [246] = 111;
  3005. X    IMP_chmap [247] = 10;
  3006. X    IMP_chmap [248] = 5;
  3007. X    IMP_chmap [249] = 117;
  3008. X    IMP_chmap [250] = 117;
  3009. X    IMP_chmap [251] = 117;
  3010. X    IMP_chmap [252] = 117;
  3011. X    IMP_chmap [253] = 121;
  3012. X    IMP_chmap [254] = 32;
  3013. X    IMP_chmap [255] = 121;
  3014. X}
  3015. XIMAGEN_createmap(name,map) 
  3016. Xunsigned short *map; 
  3017. Xint name; 
  3018. X{ 
  3019. X    register int i,j; 
  3020. X    unsigned char s[4], *p; 
  3021. X    p = s; 
  3022. X    *p++ = imP_CREATE_MAP; 
  3023. X    *p++ = name; 
  3024. X    j = 0; 
  3025. X    for (i=0;i<127;i++) { 
  3026. X        if ( map[i] ) j++; 
  3027. X    } 
  3028. X    *p = j; 
  3029. X    for (i=0;i<3;i++) putc(s[i],outfile); 
  3030. X    s[3] = 1;
  3031. X    for (j=0;j<127;j++) { 
  3032. X        if ( map[j] ) { 
  3033. X            p = s; 
  3034. X            *p++ = j; 
  3035. X            *p++ = map[j] >> 8; 
  3036. X            *p   = map[j] & 255;
  3037. X            for (i=0;i<4;i++) putc(s[i],outfile); 
  3038. X        } 
  3039. X    } 
  3040. X} 
  3041. END_OF_FILE
  3042.   if test 17380 -ne `wc -c <'gnuplot/term/imagen.trm'`; then
  3043.     echo shar: \"'gnuplot/term/imagen.trm'\" unpacked with wrong size!
  3044.   fi
  3045.   # end of 'gnuplot/term/imagen.trm'
  3046. fi
  3047. echo shar: End of archive 5 \(of 33\).
  3048. cp /dev/null ark5isdone
  3049. MISSING=""
  3050. 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
  3051.     if test ! -f ark${I}isdone ; then
  3052.     MISSING="${MISSING} ${I}"
  3053.     fi
  3054. done
  3055. if test "${MISSING}" = "" ; then
  3056.     echo You have unpacked all 33 archives.
  3057.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3058. else
  3059.     echo You still must unpack the following archives:
  3060.     echo "        " ${MISSING}
  3061. fi
  3062. exit 0
  3063. exit 0 # Just in case...
  3064.