home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *RCSid = "$Id: plot.c,v 1.65 1995/12/07 21:41:08 drd Exp $";
- #endif
-
-
- /* GNUPLOT - plot.c */
- /*
- * Copyright (C) 1986 - 1993 Thomas Williams, Colin Kelley
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the modified code. Modifications are to be distributed
- * as patches to released version.
- *
- * This software is provided "as is" without express or implied warranty.
- *
- *
- * AUTHORS
- *
- * Original Software:
- * Thomas Williams, Colin Kelley.
- *
- * Gnuplot 2.0 additions:
- * Russell Lang, Dave Kotz, John Campbell.
- *
- * Gnuplot 3.0 additions:
- * Gershon Elber and many others.
- *
- * There is a mailing list for gnuplot users. Note, however, that the
- * newsgroup
- * comp.graphics.gnuplot
- * is identical to the mailing list (they
- * both carry the same set of messages). We prefer that you read the
- * messages through that newsgroup, to subscribing to the mailing list.
- * (If you can read that newsgroup, and are already on the mailing list,
- * please send a message info-gnuplot-request@dartmouth.edu, asking to be
- * removed from the mailing list.)
- *
- * The address for mailing to list members is
- * info-gnuplot@dartmouth.edu
- * and for mailing administrative requests is
- * info-gnuplot-request@dartmouth.edu
- * The mailing list for bug reports is
- * bug-gnuplot@dartmouth.edu
- * The list of those interested in beta-test versions is
- * info-gnuplot-beta@dartmouth.edu
- */
-
- #include <signal.h>
-
- #include "plot.h"
- #include "fit.h"
- #include "setshow.h"
- #include "fnproto.h"
- #if defined(MSDOS) || defined(DOS386)
- #include <io.h>
- #endif
- #ifdef vms
- #ifndef __GNUC__
- #include <unixio.h>
- #endif
- #include <smgdef.h>
- extern int vms_vkid;
- extern smg$create_virtual_keyboard();
- #endif
- #ifdef AMIGA_SC_6_1
- #include <proto/dos.h>
- #endif
-
- #ifdef _Windows
- #include <windows.h>
- #ifndef SIGINT
- #define SIGINT 2 /* for MSC */
- #endif
- #endif
-
- extern FILE *outfile;
- extern TBOOLEAN term_graphics, term_suspended;
-
- TBOOLEAN interactive = TRUE; /* FALSE if stdin not a terminal */
- TBOOLEAN noinputfiles = TRUE; /* FALSE if there are script files */
-
- /* these 2 could be in misc.c, but are here with all the other globals */
- TBOOLEAN do_load_arg_substitution = FALSE;
- char *call_args[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
-
- char *infile_name = NULL; /* name of command file; NULL if terminal */
-
- #if defined(__TURBOC__) && (defined(MSDOS) || defined(DOS386)) /* patch to get home dir, see command.c */
- #include <string.h>
- char HelpFile[80] ;
- #endif /* - DJL */
-
- #ifndef STDOUT
- #define STDOUT 1
- #endif
-
- #ifdef _Windows
- jmp_buf far env;
- #else
- jmp_buf env;
- #endif
-
- int main __P((int argc, char **argv));
- static void load_rcfile __P((void));
- RETSIGTYPE inter __P((int anint));
-
- struct ft_entry GPFAR ft[] = { /* built-in function table */
-
- /* internal functions: */
- {"push", (FUNC_PTR)f_push}, {"pushc", (FUNC_PTR)f_pushc},
- {"pushd1", (FUNC_PTR)f_pushd1}, {"pushd2", (FUNC_PTR)f_pushd2},
- {"pushd", (FUNC_PTR)f_pushd}, {"call", (FUNC_PTR)f_call},
- {"calln", (FUNC_PTR)f_calln}, {"lnot", (FUNC_PTR)f_lnot},
- {"bnot", (FUNC_PTR)f_bnot}, {"uminus", (FUNC_PTR)f_uminus},
- {"lor", (FUNC_PTR)f_lor}, {"land", (FUNC_PTR)f_land},
- {"bor", (FUNC_PTR)f_bor}, {"xor", (FUNC_PTR)f_xor},
- {"band", (FUNC_PTR)f_band}, {"eq", (FUNC_PTR)f_eq},
- {"ne", (FUNC_PTR)f_ne}, {"gt", (FUNC_PTR)f_gt},
- {"lt", (FUNC_PTR)f_lt}, {"ge", (FUNC_PTR)f_ge},
- {"le", (FUNC_PTR)f_le}, {"plus", (FUNC_PTR)f_plus},
- {"minus", (FUNC_PTR)f_minus}, {"mult", (FUNC_PTR)f_mult},
- {"div", (FUNC_PTR)f_div}, {"mod", (FUNC_PTR)f_mod},
- {"power", (FUNC_PTR)f_power}, {"factorial", (FUNC_PTR)f_factorial},
- {"bool", (FUNC_PTR)f_bool},
- {"dollars", (FUNC_PTR)f_dollars}, /* for using extension */
-
- {"jump", f_jump}, {"jumpz", f_jumpz},
- {"jumpnz",f_jumpnz}, {"jtern", f_jtern},
-
- /* standard functions: */
- {"real", (FUNC_PTR)f_real}, {"imag", (FUNC_PTR)f_imag},
- {"arg", (FUNC_PTR)f_arg}, {"conjg", (FUNC_PTR)f_conjg},
- {"sin", (FUNC_PTR)f_sin}, {"cos", (FUNC_PTR)f_cos},
- {"tan", (FUNC_PTR)f_tan}, {"asin", (FUNC_PTR)f_asin},
- {"acos", (FUNC_PTR)f_acos}, {"atan", (FUNC_PTR)f_atan},
- {"sinh", (FUNC_PTR)f_sinh}, {"cosh", (FUNC_PTR)f_cosh},
- {"tanh", (FUNC_PTR)f_tanh}, {"int", (FUNC_PTR)f_int},
- {"abs", (FUNC_PTR)f_abs}, {"sgn", (FUNC_PTR)f_sgn},
- {"sqrt", (FUNC_PTR)f_sqrt}, {"exp", (FUNC_PTR)f_exp},
- {"log10", (FUNC_PTR)f_log10}, {"log", (FUNC_PTR)f_log},
- {"besj0", (FUNC_PTR)f_besj0}, {"besj1", (FUNC_PTR)f_besj1},
- {"besy0", (FUNC_PTR)f_besy0}, {"besy1", (FUNC_PTR)f_besy1},
- {"erf", (FUNC_PTR)f_erf}, {"erfc", (FUNC_PTR)f_erfc},
- {"gamma", (FUNC_PTR)f_gamma}, {"lgamma", (FUNC_PTR)f_lgamma},
- {"ibeta", (FUNC_PTR)f_ibeta}, {"igamma", (FUNC_PTR)f_igamma},
- {"rand", (FUNC_PTR)f_rand}, {"floor", (FUNC_PTR)f_floor},
- {"ceil", (FUNC_PTR)f_ceil},
-
- {"norm", (FUNC_PTR)f_normal}, /* XXX-JG */
- {"inverf", (FUNC_PTR)f_inverse_erf}, /* XXX-JG */
- {"invnorm", (FUNC_PTR)f_inverse_normal}, /* XXX-JG */
- {"column", (FUNC_PTR)f_column}, /* for using */
- {"valid", (FUNC_PTR)f_valid}, /* for using */
-
- {NULL, NULL}
- };
-
- static struct udvt_entry udv_pi = {NULL, "pi",FALSE};
- /* first in linked list */
- struct udvt_entry *first_udv = &udv_pi;
- struct udft_entry *first_udf = NULL;
-
-
-
- #ifdef vms
-
- #define HOME "sys$login:"
-
- #else /* vms */
- #if defined(MSDOS) || defined(AMIGA_AC_5) || defined(AMIGA_SC_6_1) || defined(ATARI) || defined(OS2) || defined(_Windows) || defined(DOS386)
-
- #define HOME "GNUPLOT"
-
- #else /* MSDOS || AMIGA || ATARI || OS2 || _Windows || defined(DOS386)*/
-
- #define HOME "HOME"
-
- #endif /* MSDOS || AMIGA || ATARI || OS2 || _Windows || defined(DOS386)*/
- #endif /* vms */
-
- #ifdef OS2
- #define INCL_DOS
- #define INCL_REXXSAA
- #include <os2.h>
- #include <process.h>
- ULONG RexxInterface( PRXSTRING, PUSHORT, PRXSTRING ) ;
- int ExecuteMacro( char* ) ;
- #endif
-
- #if defined(unix) || defined(AMIGA_AC_5) || defined(AMIGA_SC_6_1) || defined(OSK)
- #define PLOTRC ".gnuplot"
- #else /* AMIGA || unix */
- #define PLOTRC "gnuplot.ini"
- #endif /* AMIGA || unix */
-
- #if defined(ATARI) || defined(MTOS)
- void appl_exit(void);
- void MTOS_open_pipe(void);
- extern int aesid;
- #endif
-
- RETSIGTYPE inter (anint)
- int anint;
- {
- #ifdef OS2
- (void) signal(anint, SIG_ACK);
- #else
- (void) signal(SIGINT, (sigfunc)inter);
- #endif
-
- #ifndef DOSX286
- (void) signal(SIGFPE, SIG_DFL); /* turn off FPE trapping */
- #endif
- if (term && term_init)
- (*term->text)(); /* hopefully reset text mode */
- (void) fflush(outfile);
- (void) putc('\n',stderr);
- longjmp(env, TRUE); /* return to prompt */
- }
-
-
- #ifdef _Windows
- int gnu_main(argc, argv)
- #else
- int main(argc, argv)
- #endif
- int argc;
- char **argv;
- {
- #ifdef LINUX
- LINUX_setup();
- #endif
- /* make sure that we really have revoked root access, this might happen if
- gnuplot is compiled without vga support but is installed suid by mistake */
- #ifdef __linux__
- setuid(getuid());
- #endif
- #if defined(MSDOS) && !defined(_Windows) && !defined(__GNUC__)
- PC_setup();
- #endif /* MSDOS !Windows */
-
- #ifdef OSK /* malloc large blocks, otherwise problems with fragmented mem */
- _mallocmin (102400);
- #endif
-
- #ifdef MALLOCDEBUG
- malloc_debug(7);
- #endif
-
- #ifndef DOSX286
- #ifndef _Windows
- #if defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))
- strcpy (HelpFile,argv[0]) ; /* got helpfile from */
- strcpy (strrchr(HelpFile,'\\'),"\\gnuplot.gih") ; /* home directory */
- /* - DJL */
- #endif
- #endif
- #endif
-
- #ifdef VMS
- unsigned int status[2] = {1, 0};
- #endif
-
- #ifdef X11
- { extern int X11_args __P((int argc, char *argv[]));
- int n = X11_args(argc, argv);
- argv += n;
- argc -= n;
- }
- #endif
-
- #ifdef apollo
- apollo_pfm_catch();
- #endif
-
- /* moved to ATARI_init in atariaes.trm */
- /* #ifdef ATARI
- void application_init(void);
- application_init();
- #endif */
-
- #ifdef MTOS
- MTOS_open_pipe();
- #endif
-
- #ifdef OS2
- RexxRegisterSubcomExe( "GNUPLOT", (PFN) RexxInterface, NULL ) ;
- #endif
-
- setbuf(stderr,(char *)NULL);
- #ifdef UNIX
- setlinebuf(stdout);
- #endif
- outfile = stdout;
- (void) Gcomplex(&udv_pi.udv_value, Pi, 0.0);
-
- init_memory();
-
- interactive = FALSE;
- init_terminal(); /* can set term type if it likes */
-
- #ifdef AMIGA_SC_6_1
- if (IsInteractive(Input()) == DOSTRUE) interactive = TRUE;
- else interactive = FALSE;
- #else
- #if (defined(__MSC__) && defined(_Windows)) || defined(__WIN32__)
- interactive = TRUE;
- #else
- interactive = isatty(fileno(stdin));
- #endif
- #endif
- if (argc > 1)
- interactive = noinputfiles = FALSE;
- else
- noinputfiles = TRUE;
-
- if (interactive)
- show_version();
- #ifdef vms /* initialise screen management routines for command recall */
- if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
- done(status[1]);
- #endif
-
- if (!setjmp(env)) {
- /* first time */
- interrupt_setup();
- load_rcfile();
- init_fit (); /* Initialization of fitting module */
-
- if (interactive && term != 0) /* not unknown */
- fprintf(stderr, "\nTerminal type set to '%s'\n",
- term->name);
- } else {
- /* come back here from int_error() */
- #ifdef AMIGA_SC_6_1
- (void) rawcon(0);
- #endif
- load_file_error(); /* if we were in load_file(), cleanup */
- #ifdef _Windows
- SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
- #endif
- #ifdef vms
- /* after catching interrupt */
- /* VAX stuffs up stdout on SIGINT while writing to stdout,
- so reopen stdout. */
- if (outfile == stdout) {
- if ( (stdout = freopen("SYS$OUTPUT","w",stdout)) == NULL) {
- /* couldn't reopen it so try opening it instead */
- if ( (stdout = fopen("SYS$OUTPUT","w")) == NULL) {
- /* don't use int_error here - causes infinite loop! */
- fprintf(stderr,"Error opening SYS$OUTPUT as stdout\n");
- }
- }
- outfile = stdout;
- }
- #endif /* VMS */
- if (!interactive && !noinputfiles) {
- if (term && term_init)
- (*term->reset)();
- #ifdef vms
- vms_reset();
- #endif
- #if defined(ATARI) || defined(MTOS)
- if (aesid > -1) atexit(appl_exit);
- #endif
- return(IO_ERROR); /* exit on non-interactive error */
- }
- }
-
- if (argc > 1) {
- /* load filenames given as arguments */
- while (--argc > 0) {
- ++argv;
- c_token = NO_CARET; /* in case of file not found */
- load_file(fopen(*argv,"r"), *argv, FALSE); }
- } else {
- /* take commands from stdin */
- while(!com_line());
- }
-
- if (term_graphics)
- {
- /* end-of-file while plot active */
-
- if (multiplot && term_suspended && term->resume)
- {
- (*term->resume)();
- term_suspended = FALSE;
- }
- (*term->text)();
- term_graphics = FALSE;
- }
-
- if (term && term_init)
- (*term->reset)();
- #ifdef vms
- vms_reset();
- #endif
- #ifdef OS2
- RexxDeregisterSubcom( "GNUPLOT", NULL ) ;
- #endif
- #if defined(ATARI) || defined(MTOS)
- if (aesid > -1) atexit(appl_exit);
- #endif
- return(IO_SUCCESS);
- }
-
- #if (defined(ATARI) && defined(__PUREC__)) || (defined(MTOS) && defined(__PUREC__))
- #include <math.h>
- int purec_matherr(struct exception *e)
- { char *c;
- switch (e->type) {
- case DOMAIN: c = "domain error"; break;
- case SING : c = "argument singularity"; break;
- case OVERFLOW: c = "overflow range"; break;
- case UNDERFLOW: c = "underflow range"; break;
- default: c = "(unknown error"; break;
- }
- fprintf(stderr, "math exception : %s\n", c);
- fprintf(stderr, " name : %s\n", e->name);
- fprintf(stderr, " arg 1: %e\n", e->arg1);
- fprintf(stderr, " arg 2: %e\n", e->arg2);
- fprintf(stderr, " ret : %e\n", e->retval);
- return 1;
- }
- #endif
-
-
- /* Set up to catch interrupts */
- void interrupt_setup()
- {
- #ifdef __PUREC__
- setmatherr(purec_matherr);
- #endif
-
- (void) signal(SIGINT, (sigfunc)inter);
-
- /* ignore pipe errors, this might happen with set output "|head" */
- #ifdef SIGPIPE
- (void) signal(SIGPIPE, SIG_IGN);
- #endif /* SIGPIPE */
- }
-
-
- /* Look for a gnuplot start-up file */
- static void load_rcfile()
- {
- register FILE *plotrc;
- char home[80];
- char rcfile[sizeof(PLOTRC)+80];
- #if defined(ATARI) || defined(MTOS)
- #include <support.h>
- char *ini_ptr;
- char const *const ext[] = {NULL};
- #endif
- /* Look for a gnuplot init file in . or home directory */
- #ifdef vms
- (void) strcpy(home,HOME);
- #else /* vms */
- char *tmp_home=getenv(HOME);
- char *p; /* points to last char in home path, or to \0, if none */
- char c='\0';/* character that should be added, or \0, if none */
-
- if(tmp_home) {
- strcpy(home,tmp_home);
- if( strlen(home) ) p = &home[strlen(home)-1];
- else p = home;
- #if defined(MSDOS) || defined(ATARI) || defined( OS2 ) || defined(_Windows) || defined(DOS386)
- if( *p!='\\' && *p!='\0' ) c='\\';
- #else
- #if defined(MTOS)
- if( *p!='\\' && *p!='/' && *p!='\0' ) c='\\';
- #else
- #if defined(AMIGA_AC_5)
- if( *p!='/' && *p!=':' && *p!='\0' ) c='/';
- #else /* that leaves unix and OSK */
- c='/';
- #endif
- #endif
- #endif
- if(c) {
- if(*p) p++;
- *p++=c;
- *p='\0';
- }
- }
- #endif /* vms */
-
- #ifdef NOCWDRC
- /* inhibit check of init file in current directory for security reasons */
- {
- #else
- (void) strcpy(rcfile, PLOTRC);
- plotrc = fopen(rcfile,"r");
- if (plotrc == (FILE *)NULL) {
- #endif
- #ifndef vms
- if( tmp_home ) {
- #endif
- (void) sprintf(rcfile, "%s%s", home, PLOTRC);
- plotrc = fopen(rcfile,"r");
- #if defined(ATARI) || defined(MTOS)
- }
- if (plotrc == (FILE *)NULL) {
- ini_ptr = findfile(PLOTRC,getenv("GNUPLOTPATH"),ext);
- if (ini_ptr) plotrc = fopen(ini_ptr,"r");
- }
- #endif
- #if !defined(vms) && !defined(ATARI) && !defined(MTOS)
- } else
- plotrc=NULL;
- #endif
- }
- if (plotrc)
- load_file(plotrc, rcfile, FALSE);
- }
- #ifdef OS2
- int ExecuteMacro( char *pszName )
- {
- RXSTRING argv[1] ;
- RXSTRING rxRc ;
- char pszRc[256] ;
- LONG lRc ;
- HAB hab ;
- int rc ;
-
- MAKERXSTRING( argv[0], pszName, strlen( pszName ) ) ;
- MAKERXSTRING( rxRc, pszRc, 256 ) ;
-
- rc = RexxStart( 1,
- argv,
- pszName,
- NULL,
- "GNUPLOT",
- RXCOMMAND,
- NULL,
- &lRc,
- &rxRc ) ;
- if(rc==-4)rc=0; /*run was cancelled-don't give error message*/
- return rc ;
- }
-
- ULONG RexxInterface( PRXSTRING rxCmd, PUSHORT pusErr, PRXSTRING rxRc )
- /*
- ** Rexx command line interface
- */
- {
- int iCmd ;
- int rc ;
- static jmp_buf keepenv;
- memcpy( keepenv, env, sizeof(jmp_buf)) ;
- if (!setjmp(env)) {
- set_input_line( rxCmd->strptr, rxCmd->strlength ) ;
- rc = do_line() ;
- *pusErr = RXSUBCOM_OK ;
- rxRc->strptr[0] = rc + '0' ;
- rxRc->strptr[1] = '\0' ;
- rxRc->strlength = strlen( rxRc->strptr ) ;
- } else {
- *pusErr = RXSUBCOM_ERROR ;
- RexxSetHalt( getpid(), 1 ) ;
- }
- memcpy( env, keepenv, sizeof(jmp_buf)) ;
- return 0 ;
- }
- #endif
-
-