home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / GNU / GNUPLOTsrc.lha / plot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-22  |  14.9 KB  |  574 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: plot.c,v 1.65 1995/12/07 21:41:08 drd Exp $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - plot.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  * 
  25.  *   Original Software:
  26.  *     Thomas Williams,  Colin Kelley.
  27.  * 
  28.  *   Gnuplot 2.0 additions:
  29.  *       Russell Lang, Dave Kotz, John Campbell.
  30.  *
  31.  *   Gnuplot 3.0 additions:
  32.  *       Gershon Elber and many others.
  33.  * 
  34.  * There is a mailing list for gnuplot users. Note, however, that the
  35.  * newsgroup 
  36.  *    comp.graphics.gnuplot 
  37.  * is identical to the mailing list (they
  38.  * both carry the same set of messages). We prefer that you read the
  39.  * messages through that newsgroup, to subscribing to the mailing list.
  40.  * (If you can read that newsgroup, and are already on the mailing list,
  41.  * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  42.  * removed from the mailing list.)
  43.  *
  44.  * The address for mailing to list members is
  45.  *       info-gnuplot@dartmouth.edu
  46.  * and for mailing administrative requests is 
  47.  *       info-gnuplot-request@dartmouth.edu
  48.  * The mailing list for bug reports is 
  49.  *       bug-gnuplot@dartmouth.edu
  50.  * The list of those interested in beta-test versions is
  51.  *       info-gnuplot-beta@dartmouth.edu
  52.  */
  53.  
  54. #include <signal.h>
  55.  
  56. #include "plot.h"
  57. #include "fit.h"
  58. #include "setshow.h"
  59. #include "fnproto.h"
  60. #if defined(MSDOS) || defined(DOS386)
  61. #include <io.h>
  62. #endif
  63. #ifdef vms
  64. #ifndef __GNUC__
  65. #include <unixio.h>
  66. #endif
  67. #include <smgdef.h>
  68. extern int vms_vkid;
  69. extern smg$create_virtual_keyboard();
  70. #endif
  71. #ifdef AMIGA_SC_6_1
  72. #include <proto/dos.h>
  73. #endif
  74.  
  75. #ifdef _Windows
  76. #include <windows.h>
  77. #ifndef SIGINT
  78. #define SIGINT 2    /* for MSC */
  79. #endif
  80. #endif
  81.  
  82. extern FILE *outfile;
  83. extern TBOOLEAN term_graphics, term_suspended;
  84.  
  85. TBOOLEAN interactive = TRUE;    /* FALSE if stdin not a terminal */
  86. TBOOLEAN noinputfiles = TRUE;    /* FALSE if there are script files */
  87.  
  88. /*  these 2 could be in misc.c, but are here with all the other globals */
  89. TBOOLEAN do_load_arg_substitution = FALSE;
  90. char *call_args[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  91.  
  92. char *infile_name = NULL;    /* name of command file; NULL if terminal */
  93.  
  94. #if defined(__TURBOC__) && (defined(MSDOS) || defined(DOS386))  /* patch to get home dir, see command.c */
  95. #include <string.h>
  96. char HelpFile[80] ;
  97. #endif             /*   - DJL */
  98.  
  99. #ifndef STDOUT
  100. #define STDOUT 1
  101. #endif
  102.  
  103. #ifdef _Windows
  104. jmp_buf far env;
  105. #else
  106. jmp_buf env;
  107. #endif
  108.  
  109. int main __P((int argc, char **argv));
  110. static void load_rcfile __P((void));
  111. RETSIGTYPE inter __P((int anint));
  112.  
  113. struct ft_entry GPFAR ft[] = {    /* built-in function table */
  114.  
  115. /* internal functions: */
  116.     {"push", (FUNC_PTR)f_push},    {"pushc", (FUNC_PTR)f_pushc},
  117.     {"pushd1", (FUNC_PTR)f_pushd1},    {"pushd2", (FUNC_PTR)f_pushd2},
  118.     {"pushd", (FUNC_PTR)f_pushd},    {"call", (FUNC_PTR)f_call},
  119.     {"calln", (FUNC_PTR)f_calln},    {"lnot", (FUNC_PTR)f_lnot},
  120.     {"bnot", (FUNC_PTR)f_bnot},    {"uminus", (FUNC_PTR)f_uminus},
  121.     {"lor", (FUNC_PTR)f_lor},    {"land", (FUNC_PTR)f_land},
  122.     {"bor", (FUNC_PTR)f_bor},    {"xor", (FUNC_PTR)f_xor},
  123.     {"band", (FUNC_PTR)f_band},    {"eq", (FUNC_PTR)f_eq},    
  124.     {"ne", (FUNC_PTR)f_ne},        {"gt", (FUNC_PTR)f_gt},
  125.     {"lt", (FUNC_PTR)f_lt},        {"ge", (FUNC_PTR)f_ge},
  126.     {"le", (FUNC_PTR)f_le},        {"plus", (FUNC_PTR)f_plus},
  127.     {"minus", (FUNC_PTR)f_minus},    {"mult", (FUNC_PTR)f_mult},
  128.     {"div", (FUNC_PTR)f_div},    {"mod", (FUNC_PTR)f_mod},
  129.     {"power", (FUNC_PTR)f_power},    {"factorial", (FUNC_PTR)f_factorial},
  130.     {"bool", (FUNC_PTR)f_bool},
  131.     {"dollars", (FUNC_PTR)f_dollars},  /* for using extension */
  132.  
  133.     {"jump", f_jump},        {"jumpz", f_jumpz},
  134.     {"jumpnz",f_jumpnz},        {"jtern", f_jtern},
  135.  
  136. /* standard functions: */
  137.     {"real", (FUNC_PTR)f_real},    {"imag", (FUNC_PTR)f_imag},
  138.     {"arg", (FUNC_PTR)f_arg},    {"conjg", (FUNC_PTR)f_conjg},
  139.     {"sin", (FUNC_PTR)f_sin},    {"cos", (FUNC_PTR)f_cos},
  140.     {"tan", (FUNC_PTR)f_tan},    {"asin", (FUNC_PTR)f_asin},
  141.     {"acos", (FUNC_PTR)f_acos},    {"atan", (FUNC_PTR)f_atan},
  142.     {"sinh", (FUNC_PTR)f_sinh},    {"cosh", (FUNC_PTR)f_cosh},
  143.     {"tanh", (FUNC_PTR)f_tanh},    {"int", (FUNC_PTR)f_int},
  144.     {"abs", (FUNC_PTR)f_abs},    {"sgn", (FUNC_PTR)f_sgn},
  145.     {"sqrt", (FUNC_PTR)f_sqrt},    {"exp", (FUNC_PTR)f_exp},
  146.     {"log10", (FUNC_PTR)f_log10},    {"log", (FUNC_PTR)f_log},
  147.     {"besj0", (FUNC_PTR)f_besj0},    {"besj1", (FUNC_PTR)f_besj1},
  148.     {"besy0", (FUNC_PTR)f_besy0},    {"besy1", (FUNC_PTR)f_besy1},
  149.         {"erf", (FUNC_PTR)f_erf},    {"erfc", (FUNC_PTR)f_erfc},
  150.     {"gamma", (FUNC_PTR)f_gamma},    {"lgamma", (FUNC_PTR)f_lgamma},
  151.         {"ibeta", (FUNC_PTR)f_ibeta},    {"igamma", (FUNC_PTR)f_igamma},
  152.     {"rand", (FUNC_PTR)f_rand},    {"floor", (FUNC_PTR)f_floor},
  153.     {"ceil", (FUNC_PTR)f_ceil},
  154.  
  155.     {"norm", (FUNC_PTR)f_normal},            /* XXX-JG */
  156.     {"inverf", (FUNC_PTR)f_inverse_erf},        /* XXX-JG */
  157.     {"invnorm", (FUNC_PTR)f_inverse_normal},    /* XXX-JG */
  158.     {"column", (FUNC_PTR)f_column},   /* for using */
  159.     {"valid",  (FUNC_PTR)f_valid},    /* for using */
  160.  
  161.     {NULL, NULL}
  162. };
  163.  
  164. static struct udvt_entry udv_pi = {NULL, "pi",FALSE};
  165.                                     /* first in linked list */
  166. struct udvt_entry *first_udv = &udv_pi;
  167. struct udft_entry *first_udf = NULL;
  168.  
  169.  
  170.  
  171. #ifdef vms
  172.  
  173. #define HOME "sys$login:"
  174.  
  175. #else /* vms */
  176. #if defined(MSDOS) ||  defined(AMIGA_AC_5) || defined(AMIGA_SC_6_1) || defined(ATARI) || defined(OS2) || defined(_Windows) || defined(DOS386)
  177.  
  178. #define HOME "GNUPLOT"
  179.  
  180. #else /* MSDOS || AMIGA || ATARI || OS2 || _Windows || defined(DOS386)*/
  181.  
  182. #define HOME "HOME"
  183.  
  184. #endif /* MSDOS || AMIGA || ATARI || OS2 || _Windows || defined(DOS386)*/
  185. #endif /* vms */
  186.  
  187. #ifdef OS2
  188. #define INCL_DOS
  189. #define INCL_REXXSAA
  190. #include <os2.h>
  191. #include <process.h>
  192. ULONG RexxInterface( PRXSTRING, PUSHORT, PRXSTRING ) ;
  193. int   ExecuteMacro( char* ) ;  
  194. #endif
  195.  
  196. #if defined(unix) || defined(AMIGA_AC_5) || defined(AMIGA_SC_6_1) || defined(OSK)
  197. #define PLOTRC ".gnuplot"
  198. #else /* AMIGA || unix */
  199. #define PLOTRC "gnuplot.ini"
  200. #endif /* AMIGA || unix */
  201.  
  202. #if defined(ATARI) || defined(MTOS)
  203. void appl_exit(void);
  204. void MTOS_open_pipe(void);
  205. extern int aesid;
  206. #endif
  207.  
  208. RETSIGTYPE inter (anint)
  209. int anint;
  210. {
  211. #ifdef OS2
  212.         (void) signal(anint, SIG_ACK);
  213. #else
  214.         (void) signal(SIGINT, (sigfunc)inter);
  215. #endif
  216.  
  217. #ifndef DOSX286
  218.     (void) signal(SIGFPE, SIG_DFL);    /* turn off FPE trapping */
  219. #endif
  220.     if (term && term_init)
  221.         (*term->text)();    /* hopefully reset text mode */
  222.     (void) fflush(outfile);
  223.     (void) putc('\n',stderr);
  224.     longjmp(env, TRUE);        /* return to prompt */
  225. }
  226.  
  227.  
  228. #ifdef _Windows
  229. int gnu_main(argc, argv)
  230. #else
  231. int main(argc, argv)
  232. #endif
  233.     int argc;
  234.     char **argv;
  235. {
  236. #ifdef LINUX
  237.     LINUX_setup();
  238. #endif
  239. /* make sure that we really have revoked root access, this might happen if
  240.    gnuplot is compiled without vga support but is installed suid by mistake */
  241. #ifdef __linux__
  242.     setuid(getuid());
  243. #endif
  244. #if defined(MSDOS) && !defined(_Windows) && !defined(__GNUC__)
  245.   PC_setup();
  246. #endif /* MSDOS !Windows */
  247.  
  248. #ifdef OSK    /* malloc large blocks, otherwise problems with fragmented mem */
  249.    _mallocmin (102400);
  250. #endif
  251.     
  252. #ifdef MALLOCDEBUG
  253. malloc_debug(7);
  254. #endif
  255.  
  256. #ifndef DOSX286
  257. #ifndef _Windows
  258. #if defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))
  259. strcpy (HelpFile,argv[0]) ;                       /* got helpfile from */
  260. strcpy (strrchr(HelpFile,'\\'),"\\gnuplot.gih") ; /* home directory    */
  261.                                                   /*   - DJL */
  262. #endif
  263. #endif
  264. #endif
  265.  
  266. #ifdef VMS
  267. unsigned int status[2] = {1, 0};
  268. #endif
  269.  
  270. #ifdef X11
  271.      { extern int X11_args __P((int argc, char *argv[]));
  272.        int n = X11_args(argc, argv);
  273.        argv += n;
  274.        argc -= n;
  275.      }
  276. #endif 
  277.  
  278. #ifdef apollo
  279.     apollo_pfm_catch();
  280. #endif
  281.  
  282. /* moved to ATARI_init in atariaes.trm */
  283. /* #ifdef ATARI
  284.     void application_init(void);
  285.     application_init();
  286. #endif */ 
  287.  
  288. #ifdef MTOS
  289.     MTOS_open_pipe();
  290. #endif
  291.  
  292. #ifdef OS2
  293.      RexxRegisterSubcomExe( "GNUPLOT", (PFN) RexxInterface, NULL ) ;
  294. #endif
  295.  
  296.     setbuf(stderr,(char *)NULL);
  297. #ifdef UNIX
  298.     setlinebuf(stdout);
  299. #endif
  300.     outfile = stdout;
  301.     (void) Gcomplex(&udv_pi.udv_value, Pi, 0.0);
  302.  
  303.      init_memory();
  304.  
  305.      interactive = FALSE;
  306.      init_terminal();        /* can set term type if it likes */
  307.  
  308. #ifdef AMIGA_SC_6_1
  309.      if (IsInteractive(Input()) == DOSTRUE) interactive = TRUE;
  310.      else interactive = FALSE;
  311. #else
  312. #if (defined(__MSC__) && defined(_Windows)) || defined(__WIN32__)
  313.      interactive = TRUE;
  314. #else
  315.      interactive = isatty(fileno(stdin));
  316. #endif
  317. #endif
  318.      if (argc > 1)
  319.       interactive = noinputfiles = FALSE;
  320.      else
  321.       noinputfiles = TRUE;
  322.  
  323.      if (interactive)
  324.       show_version();
  325. #ifdef vms   /* initialise screen management routines for command recall */
  326.           if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
  327.                done(status[1]);
  328. #endif
  329.  
  330.     if (!setjmp(env)) {
  331.         /* first time */
  332.         interrupt_setup();
  333.         load_rcfile();
  334.         init_fit ();    /* Initialization of fitting module */
  335.  
  336.         if (interactive && term != 0)    /* not unknown */
  337.          fprintf(stderr, "\nTerminal type set to '%s'\n", 
  338.                 term->name);
  339.     } else {    
  340.         /* come back here from int_error() */
  341. #ifdef AMIGA_SC_6_1
  342.         (void) rawcon(0);
  343. #endif
  344.         load_file_error();    /* if we were in load_file(), cleanup */
  345. #ifdef _Windows
  346.     SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
  347. #endif
  348. #ifdef vms
  349.         /* after catching interrupt */
  350.         /* VAX stuffs up stdout on SIGINT while writing to stdout,
  351.           so reopen stdout. */
  352.         if (outfile == stdout) {
  353.            if ( (stdout = freopen("SYS$OUTPUT","w",stdout))  == NULL) {
  354.               /* couldn't reopen it so try opening it instead */
  355.               if ( (stdout = fopen("SYS$OUTPUT","w"))  == NULL) {
  356.                  /* don't use int_error here - causes infinite loop! */
  357.                  fprintf(stderr,"Error opening SYS$OUTPUT as stdout\n");
  358.               }
  359.            }
  360.            outfile = stdout;
  361.         }
  362. #endif                    /* VMS */
  363.         if (!interactive && !noinputfiles) {
  364.             if (term && term_init)
  365.                 (*term->reset)();
  366. #ifdef vms
  367.             vms_reset();
  368. #endif
  369. #if defined(ATARI) || defined(MTOS)
  370.             if (aesid > -1) atexit(appl_exit);
  371. #endif
  372.             return(IO_ERROR);    /* exit on non-interactive error */
  373.          }
  374.     }
  375.  
  376.      if (argc > 1) {
  377.         /* load filenames given as arguments */
  378.         while (--argc > 0) {
  379.            ++argv;
  380.            c_token = NO_CARET; /* in case of file not found */
  381.            load_file(fopen(*argv,"r"), *argv, FALSE);        }
  382.     } else {
  383.         /* take commands from stdin */
  384.         while(!com_line());
  385.     }
  386.  
  387.     if (term_graphics)
  388.     {
  389.         /* end-of-file while plot active */
  390.  
  391.         if (multiplot && term_suspended && term->resume)
  392.         {
  393.             (*term->resume)();
  394.             term_suspended = FALSE;
  395.         }
  396.         (*term->text)();
  397.         term_graphics = FALSE;
  398.     }
  399.  
  400.     if (term && term_init)
  401.         (*term->reset)();
  402. #ifdef vms
  403.     vms_reset();
  404. #endif
  405. #ifdef OS2
  406.      RexxDeregisterSubcom( "GNUPLOT", NULL ) ;
  407. #endif
  408. #if defined(ATARI) || defined(MTOS)
  409.     if (aesid > -1) atexit(appl_exit);
  410. #endif
  411.     return(IO_SUCCESS);
  412. }
  413.  
  414. #if (defined(ATARI) && defined(__PUREC__)) || (defined(MTOS) && defined(__PUREC__))
  415. #include <math.h>
  416. int purec_matherr(struct exception *e)
  417. {    char *c;
  418.     switch (e->type) {
  419.         case DOMAIN:    c = "domain error"; break;
  420.         case SING  :    c = "argument singularity"; break;
  421.         case OVERFLOW:  c = "overflow range"; break;
  422.         case UNDERFLOW: c = "underflow range"; break;
  423.         default:        c = "(unknown error"; break;
  424.     }
  425.     fprintf(stderr, "math exception : %s\n", c);
  426.     fprintf(stderr, "    name : %s\n", e->name);
  427.     fprintf(stderr, "    arg 1: %e\n", e->arg1);
  428.     fprintf(stderr, "    arg 2: %e\n", e->arg2);
  429.     fprintf(stderr, "    ret  : %e\n", e->retval);
  430.     return 1;
  431. }
  432. #endif
  433.  
  434.  
  435. /* Set up to catch interrupts */
  436. void interrupt_setup()
  437. {
  438. #ifdef __PUREC__
  439.         setmatherr(purec_matherr);
  440. #endif
  441.  
  442.     (void) signal(SIGINT, (sigfunc)inter);
  443.  
  444. /* ignore pipe errors, this might happen with set output "|head" */
  445. #ifdef SIGPIPE
  446.         (void) signal(SIGPIPE, SIG_IGN);
  447. #endif /* SIGPIPE */
  448. }
  449.  
  450.  
  451. /* Look for a gnuplot start-up file */
  452. static void load_rcfile()
  453. {
  454.     register FILE *plotrc;
  455.     char home[80]; 
  456.     char rcfile[sizeof(PLOTRC)+80];
  457. #if defined(ATARI) || defined(MTOS)
  458.     #include <support.h> 
  459.     char *ini_ptr;
  460.     char const *const ext[] = {NULL};
  461. #endif
  462.     /* Look for a gnuplot init file in . or home directory */
  463. #ifdef vms
  464.     (void) strcpy(home,HOME);
  465. #else /* vms */
  466.     char *tmp_home=getenv(HOME);
  467.     char *p;    /* points to last char in home path, or to \0, if none */
  468.     char c='\0';/* character that should be added, or \0, if none */
  469.  
  470.     if(tmp_home) {
  471.         strcpy(home,tmp_home);
  472.     if( strlen(home) ) p = &home[strlen(home)-1];
  473.     else           p = home;
  474. #if defined(MSDOS) || defined(ATARI) || defined( OS2 ) || defined(_Windows) || defined(DOS386)
  475.     if( *p!='\\' && *p!='\0' ) c='\\';
  476. #else
  477. #if defined(MTOS)
  478.     if( *p!='\\' && *p!='/' && *p!='\0' ) c='\\';
  479. #else
  480. #if defined(AMIGA_AC_5)
  481.     if( *p!='/' && *p!=':' && *p!='\0' ) c='/';
  482. #else /* that leaves unix and OSK */
  483.     c='/';
  484. #endif
  485. #endif
  486. #endif
  487.     if(c) {
  488.         if(*p) p++;
  489.         *p++=c;
  490.         *p='\0';
  491.     }
  492.     }
  493. #endif /* vms */
  494.  
  495. #ifdef NOCWDRC
  496.     /* inhibit check of init file in current directory for security reasons */
  497.     {
  498. #else
  499.     (void) strcpy(rcfile, PLOTRC);
  500.     plotrc = fopen(rcfile,"r");
  501.     if (plotrc == (FILE *)NULL) {
  502. #endif
  503. #ifndef vms
  504.     if( tmp_home ) {
  505. #endif
  506.        (void) sprintf(rcfile, "%s%s", home, PLOTRC);
  507.        plotrc = fopen(rcfile,"r");
  508. #if defined(ATARI) || defined(MTOS)
  509.     }
  510.     if (plotrc == (FILE *)NULL) {
  511.        ini_ptr = findfile(PLOTRC,getenv("GNUPLOTPATH"),ext);
  512.        if (ini_ptr)  plotrc = fopen(ini_ptr,"r");
  513.         }
  514. #endif
  515. #if !defined(vms) && !defined(ATARI) && !defined(MTOS)
  516.     } else
  517.        plotrc=NULL;
  518. #endif
  519.     }
  520.     if (plotrc)
  521.      load_file(plotrc, rcfile, FALSE);
  522. }
  523. #ifdef OS2
  524. int ExecuteMacro( char *pszName ) 
  525.     {
  526.     RXSTRING argv[1] ;
  527.     RXSTRING rxRc ;
  528.     char pszRc[256] ;
  529.     LONG lRc ;
  530.     HAB hab ;
  531.     int rc ;
  532.     
  533.     MAKERXSTRING( argv[0], pszName, strlen( pszName ) ) ;
  534.     MAKERXSTRING( rxRc, pszRc, 256 ) ;
  535.  
  536.     rc = RexxStart( 1,
  537.                     argv,
  538.                     pszName,
  539.                     NULL,
  540.                     "GNUPLOT",
  541.                     RXCOMMAND,
  542.                     NULL,
  543.                     &lRc,
  544.                     &rxRc ) ;
  545.     if(rc==-4)rc=0; /*run was cancelled-don't give error message*/ 
  546.     return rc ;
  547.     }
  548.  
  549. ULONG RexxInterface( PRXSTRING rxCmd, PUSHORT pusErr, PRXSTRING rxRc ) 
  550. /*
  551. ** Rexx command line interface
  552. */
  553.     {
  554.     int iCmd ;
  555.     int rc ;
  556.     static jmp_buf keepenv;
  557.     memcpy( keepenv, env, sizeof(jmp_buf)) ;
  558.   if (!setjmp(env)) {
  559.     set_input_line( rxCmd->strptr, rxCmd->strlength ) ;
  560.     rc = do_line() ;
  561.     *pusErr = RXSUBCOM_OK ;
  562.     rxRc->strptr[0] = rc + '0' ;
  563.     rxRc->strptr[1] = '\0' ;
  564.     rxRc->strlength = strlen( rxRc->strptr ) ;    
  565.   } else {
  566.     *pusErr = RXSUBCOM_ERROR ;
  567.     RexxSetHalt( getpid(), 1 ) ;
  568.   }
  569.     memcpy( env, keepenv, sizeof(jmp_buf)) ;
  570.     return 0 ;    
  571.     }
  572. #endif
  573.  
  574.