2 static char *RCSid() { return RCSid("$Id: plot.c,v 1.90.2.5 2008/12/12 06:57:50 sfeam Exp $"); }
8 * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
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.
16 * Permission to modify the software is granted, but not the right to
17 * distribute the complete modified source code. Modifications are to
18 * be distributed as patches to the released version. Permission to
19 * distribute binaries produced by compiling modified sources is granted,
21 * 1. distribute the corresponding source modifications from the
22 * released version in the form of a patch file along with the binaries,
23 * 2. add special version identification to distinguish your version
24 * in addition to the base release version number,
25 * 3. provide your name and address as the primary contact for the
26 * support of your modified version, and
27 * 4. retain our contact information in regard to use of the base
29 * Permission to distribute the released version of the source code along
30 * with corresponding source modifications in the form of a patch file is
31 * granted with same provisions 2 through 4 for binary distributions.
33 * This software is provided "as is" without express or implied warranty
34 * to the extent permitted by applicable law.
56 #ifdef OS2 /* os2.h required for gpexecute.h */
60 # define INCL_DOSSEMAPHORES
66 # include "mouse.h" /* for mouse_setting */
67 # include "gpexecute.h"
70 /* on OS/2 this is needed even without USE_MOUSE */
71 #if defined(OS2_IPC) && !defined(USE_MOUSE)
72 # include "gpexecute.h"
75 /* Used nowhere else */
76 #ifdef HAVE_SYS_UTSNAME_H
77 # include <sys/utsname.h>
80 #if defined(MSDOS) || defined(DOS386) || defined(__EMX__)
91 extern smg$create_virtual_keyboard();
93 extern smg$create_key_table();
97 # include <proto/dos.h>
101 # include <windows.h>
103 # define SIGINT 2 /* for MSC */
105 # include "win/wgnuplib.h"
106 # include "win/wcommon.h"
107 #endif /* _Windows */
110 * Only required by two files directly,
111 * so I don't put this into a header file. -lh
113 #ifdef HAVE_LIBREADLINE
114 # ifdef GNUPLOT_HISTORY
115 # include <readline/tilde.h>
117 extern int rl_complete_with_tilde_expansion;
122 #ifdef HAVE_LIBEDITLINE
123 # include <editline/readline.h>
126 /* enable gnuplot history with readline */
127 #ifdef GNUPLOT_HISTORY
128 # ifndef GNUPLOT_HISTORY_FILE
129 # define GNUPLOT_HISTORY_FILE "~/.gnuplot_history"
132 * The next variable is a pointer to the value returned from 'tilde_expand()'.
133 * This function expands '~' to the user's home directory, or $HOME, with
134 * UN*X, AmigaOS, MSDOS.
135 * Depending on your OS you have to make sure that the "$HOME" environment
136 * variable exitsts. You are responsible for valid values.
138 static char *expanded_history_filename;
140 static void wrapper_for_write_history __PROTO((void));
142 #endif /* GNUPLOT_HISTORY */
144 TBOOLEAN interactive = TRUE; /* FALSE if stdin not a terminal */
145 static TBOOLEAN noinputfiles = TRUE; /* FALSE if there are script files */
146 TBOOLEAN persist_cl = FALSE; /* TRUE if -persist is parsed in the command line */
148 /* user home directory */
149 static const char *user_homedir = NULL;
152 const char *user_shell = NULL;
154 #if defined(ATARI) || defined(MTOS)
155 const char *user_gnuplotpath = NULL;
159 extern int X11_args __PROTO((int, char **)); /* FIXME: defined in term/x11.trm */
162 /* patch to get home dir, see command.c */
163 #if (defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))) || defined(DJGPP)
164 # include <dir.h> /* MAXPATH */
165 char HelpFile[MAXPATH];
168 /* a longjmp buffer to get back to the command line */
169 /* FIXME HBB 20001103: should probably just use GPFAR, rather than
170 * check for _Windows */
172 static JMP_BUF far command_line_env;
174 static JMP_BUF command_line_env;
177 static void load_rcfile __PROTO((void));
178 static RETSIGTYPE inter __PROTO((int anint));
179 static void init_memory __PROTO((void));
181 static int exit_status = EXIT_SUCCESS;
184 # include <process.h>
185 static ULONG RexxInterface(PRXSTRING, PUSHORT, PRXSTRING);
186 TBOOLEAN CallFromRexx = FALSE;
189 #if defined(ATARI) || defined(MTOS)
190 /* For findfile () (?) */
191 # include <support.h>
192 void appl_exit(void);
193 void MTOS_open_pipe(void);
200 (void) anint; /* aovid -Wunused warning */
201 (void) signal(SIGINT, (sigfunc) inter);
204 (void) signal(SIGFPE, SIG_DFL); /* turn off FPE trapping */
208 if (!strcmp(term->name,"pm")) {
212 LONGJMP(command_line_env, TRUE);
218 (void) putc('\n', stderr);
219 LONGJMP(command_line_env, TRUE); /* return to prompt */
224 /* utility functions to ensure that setuid gnuplot
225 * assumes root privileges only for those parts
226 * of the code which require root rights.
228 * By "Dr. Werner Fink" <werner@suse.de>
230 static uid_t euid, ruid;
231 static gid_t egid, rgid;
232 static int asked_privi = 0;
244 if (setegid(rgid) == -1)
245 (void) fprintf(stderr, "setegid(%d): %s\n",
246 (int) rgid, strerror(errno));
247 if (seteuid(ruid) == -1)
248 (void) fprintf(stderr, "seteuid(%d): %s\n",
249 (int) ruid, strerror(errno));
262 if (setegid(egid) == -1)
263 (void) fprintf(stderr, "setegid(%d): %s\n",
264 (int) egid, strerror(errno));
265 if (seteuid(euid) == -1)
266 (void) fprintf(stderr, "seteuid(%d): %s\n",
267 (int) euid, strerror(errno));
270 #endif /* LINUXVGA */
272 /* a wrapper for longjmp so we can keep everything local */
274 bail_to_command_line()
277 call_kill_pending_Pause_dialog();
279 LONGJMP(command_line_env, TRUE);
282 #if defined(_Windows) || defined(_Macintosh)
284 gnu_main(int argc, char **argv)
287 main(int argc, char **argv)
293 LINUX_setup(); /* setup VGA before dropping privilege DBT 4/5/99 */
296 /* make sure that we really have revoked root access, this might happen if
297 gnuplot is compiled without vga support but is installed suid by mistake */
302 #if defined(MSDOS) && !defined(_Windows) && !defined(__GNUC__)
304 #endif /* MSDOS !Windows */
306 /* HBB: Seems this isn't needed any more for DJGPP V2? */
307 /* HBB: disable all floating point exceptions, just keep running... */
308 #if defined(DJGPP) && (DJGPP!=2)
309 _control87(MCW_EM, MCW_EM);
315 char semInputReadyName[40];
316 sprintf( semInputReadyName, "\\SEM32\\GP%i_Input_Ready", getpid() );
317 rc = DosCreateEventSem(semInputReadyName,&semInputReady,0,0);
319 fputs("DosCreateEventSem error\n",stderr);
321 rc = RexxRegisterSubcomExe("GNUPLOT", (PFN) RexxInterface, NULL);
324 /* malloc large blocks, otherwise problems with fragmented mem */
333 /* get helpfile from home directory */
336 # if defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))
337 strcpy(HelpFile, argv[0]);
338 strcpy(strrchr(HelpFile, DIRSEP1), "\\gnuplot.gih");
340 # endif /* !_Windows */
341 #endif /* !DOSX286 */
345 strcpy(HelpFile, argv[0]);
346 for (s = HelpFile; *s; s++)
348 *s = DIRSEP2; /* '\\' to '/' */
349 strcpy(strrchr(HelpFile, DIRSEP2), "/gnuplot.gih");
350 } /* Add also some "paranoid" tests for '\\': AP */
354 unsigned int status[2] = { 1, 0 };
357 #if defined(HAVE_LIBEDITLINE)
358 rl_getc_function = getc_wrapper;
360 #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)
362 /* T.Walter 1999-06-24: 'rl_readline_name' must be this fix name.
363 * It is used to parse a 'gnuplot' specific section in '~/.inputrc' */
364 rl_readline_name = "Gnuplot";
365 rl_terminal_name = getenv("TERM");
367 #if defined(HAVE_LIBREADLINE)
368 rl_complete_with_tilde_expansion = 1;
371 for (i = 1; i < argc; i++) {
374 if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
375 printf("gnuplot %s patchlevel %s\n",
376 gnuplot_version, gnuplot_patchlevel);
378 } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
379 printf( "Usage: gnuplot [OPTION]... [FILE]\n"
381 "for X11 options see 'help X11->command-line-options'\n"
385 " -e \"command1; command2; ...\"\n"
386 "gnuplot %s patchlevel %s\n"
387 "Report bugs to %s\n",
388 gnuplot_version, gnuplot_patchlevel, bug_email);
393 /* the X11 terminal removes tokens that it recognizes from argv.
394 * We have to parse -persist for the wxWidgets terminal before it happens, and
395 * keep that value for later use */
402 if (!strcmp(argv[i], "-persist")) {
403 FPRINTF((stderr,"'persist' command line option recognized"));
418 int n = X11_args(argc, argv);
428 /* moved to ATARI_init in atariaes.trm */
430 void application_init(void);
438 setbuf(stderr, (char *) NULL);
441 /* this was once setlinebuf(). Docs say this is
442 * identical to setvbuf(,NULL,_IOLBF,0), but MS C
443 * faults this (size out of range), so we try with
444 * size of 1024 instead. [SAS/C does that, too. -lh]
445 * Failing this, I propose we just make the call and
446 * ignore the return : its probably not a big deal
448 if (setvbuf(stdout, (char *) NULL, _IOLBF, (size_t) 1024) != 0)
449 (void) fputs("Could not linebuffer stdout\n", stderr);
452 /* This call used to be in x11.trm, with the following comment:
453 * Multi-character inputs like escape sequences but also mouse-pasted
454 * text got buffered and therefore didn't trigger the select() function
455 * in X11_waitforinput(). Switching to unbuffered input solved this.
457 * But switching to unbuffered mode causes all characters in the input
458 * buffer to be lost. So the only safe time to do it is on program entry.
459 * The #ifdef X11 is probably unnecessary, but makes the change minimal.
460 * Do any non-X platforms suffer from the same problem?
463 setvbuf(stdin, (char *) NULL, _IONBF, 0);
470 /* Initialize pre-loaded user variables */
471 (void) Gcomplex(&udv_pi.udv_value, M_PI, 0.0);
473 udv_NaN = add_udv_by_name("NaN");
474 (void) Gcomplex(&(udv_NaN->udv_value), atof("NaN"), 0.0);
475 udv_NaN->udv_undef = FALSE;
481 init_terminal(); /* can set term type if it likes */
482 push_terminal(0); /* remember the default terminal */
484 /* reset the terminal when exiting */
485 /* this is done through gp_atexit so that other terminal functions
486 * can be registered to be executed before the terminal is reset. */
487 GP_ATEXIT(term_reset);
490 if (IsInteractive(Input()) == DOSTRUE)
495 # if (defined(__MSC__) && defined(_Windows)) || defined(__WIN32__)
498 interactive = isatty(fileno(stdin));
500 #endif /* !AMIGA_SC_6_1 */
503 interactive = noinputfiles = FALSE;
507 /* Need this before show_version is called for the first time */
509 #ifdef HAVE_SYS_UTSNAME_H
513 /* something is fundamentally wrong if this fails ... */
514 if (uname(&uts) > -1) {
516 strcpy(os_name, uts.sysname);
517 sprintf(os_name, "%s.%s", uts.version, uts.release);
519 strcpy(os_name, "SCO");
520 strcpy(os_rel, uts.release);
521 # elif defined(DJGPP)
522 if (!strncmp(uts.sysname, "??Un", 4)) /* don't print ??Unknow" */
523 strcpy(os_name, "Unknown");
525 strcpy(os_name, uts.sysname);
526 strcpy(os_rel, uts.release);
529 strcpy(os_name, uts.sysname);
530 strcpy(os_rel, uts.release);
532 if (!strchr(os_rel,'.'))
533 /* write either "2.40" or "4.0", or empty -- don't print "OS/2 1" */
540 #else /* ! HAVE_SYS_UTSNAME_H */
545 #endif /* HAVE_SYS_UTSNAME_H */
548 show_version(stderr);
550 show_version(NULL); /* Only load GPVAL_COMPILE_OPTIONS */
552 update_gpval_variables(3); /* update GPVAL_ variables available to user */
555 /* initialise screen management routines for command recall */
556 if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
558 if (status[1] = smg$create_key_table(&vms_ktid) != SS$_NORMAL)
562 if (!SETJMP(command_line_env, 1)) {
565 /* should move this stuff another initialisation routine,
566 * something like init_set() maybe */
570 * Now, init_fontpath is invoked when it is used first.
574 /* HBB: make sure all variables start in the same mode 'reset'
575 * would set them to. Since the axis variables aren't in
576 * initialized arrays any more, this is now necessary... */
578 init_color(); /* Initialization of color */
580 init_fit(); /* Initialization of fitting module */
582 if (interactive && term != 0) { /* not unknown */
583 #ifdef GNUPLOT_HISTORY
584 FPRINTF((stderr, "Before read_history\n"));
585 #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)
586 expanded_history_filename = tilde_expand(GNUPLOT_HISTORY_FILE);
588 expanded_history_filename = gp_strdup(GNUPLOT_HISTORY_FILE);
589 gp_expand_tilde(&expanded_history_filename);
591 FPRINTF((stderr, "expanded_history_filename = %s\n", expanded_history_filename));
592 read_history(expanded_history_filename);
594 /* BEGIN: Go local to get environment variable */
595 const char *temp_env = getenv ("GNUPLOT_HISTORY_SIZE");
597 gnuplot_history_size = strtol (temp_env, (char **) NULL, 10);
598 } /* END: Go local to get environment variable */
601 * It is safe to ignore the return values of 'atexit()' and
602 * 'on_exit()'. In the worst case, there is no history of your
603 * currrent session and you have to type all again in your next
605 * This is the default behaviour (traditional reasons), too.
606 * In case you don't have one of these functions, or you don't
607 * want to use them, 'write_history()' is called directly.
609 GP_ATEXIT(wrapper_for_write_history);
610 #endif /* GNUPLOT_HISTORY */
612 fprintf(stderr, "\nTerminal type set to '%s'\n", term->name);
613 } /* if (interactive && term != 0) */
615 /* come back here from int_error() */
616 if (interactive == FALSE)
617 exit_status = EXIT_FAILURE;
622 load_file_error(); /* if we were in load_file(), cleanup */
626 /* after catching interrupt */
627 /* VAX stuffs up stdout on SIGINT while writing to stdout,
629 if (gpoutfile == stdout) {
630 if ((stdout = freopen("SYS$OUTPUT", "w", stdout)) == NULL) {
631 /* couldn't reopen it so try opening it instead */
632 if ((stdout = fopen("SYS$OUTPUT", "w")) == NULL) {
633 /* don't use int_error here - causes infinite loop! */
634 fputs("Error opening SYS$OUTPUT as stdout\n", stderr);
640 if (!interactive && !noinputfiles) {
642 #if defined(ATARI) || defined(MTOS)
646 exit(EXIT_FAILURE); /* exit on non-interactive error */
652 TBOOLEAN noend = persist_cl;
655 /* load filenames given as arguments */
658 c_token = NO_CARET; /* in case of file not found */
660 if (stricmp(*argv, "-noend") == 0 || stricmp(*argv, "/noend") == 0
661 || stricmp(*argv, "-persist") == 0)
665 if (strcmp(*argv, "-") == 0) {
666 /* DBT 10-7-98 go interactive if "-" on command line */
669 /* will this work on all platforms? */
675 } else if (strcmp(*argv, "-e") == 0) {
678 fprintf(stderr, "syntax: gnuplot -e \"commands\"\n");
684 load_file(loadpath_fopen(*argv, "r"), *argv, FALSE);
693 /* take commands from stdin */
697 #if (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)) && defined(GNUPLOT_HISTORY)
698 #if !defined(HAVE_ATEXIT) && !defined(HAVE_ON_EXIT)
699 /* You should be here if you neither have 'atexit()' nor 'on_exit()' */
700 wrapper_for_write_history();
701 #endif /* !HAVE_ATEXIT && !HAVE_ON_EXIT */
702 #endif /* (HAVE_LIBREADLINE || HAVE_LIBEDITLINE) && GNUPLOT_HISTORY */
705 RexxDeregisterSubcom("GNUPLOT", NULL);
708 #if defined(ATARI) || defined(MTOS)
712 /* HBB 20040223: Not all compilers like exit() to end main() */
713 /* exit(exit_status); */
718 /* Set up to catch interrupts */
723 setmatherr(purec_matherr);
726 (void) signal(SIGINT, (sigfunc) inter);
729 /* ignore pipe errors, this might happen with set output "|head" */
730 (void) signal(SIGPIPE, SIG_IGN);
735 /* Look for a gnuplot init file in current or home directory */
743 /* inhibit check of init file in current directory for security reasons */
745 plotrc = fopen(PLOTRC, "r");
746 #endif /* !NOCWDRC */
748 if (plotrc == NULL) {
750 /* len of homedir + directory separator + len of file name + \0 */
751 rcfile = (char *) gp_alloc((user_homedir ? strlen(user_homedir) : 0) + 1 + strlen(PLOTRC) + 1, "rcfile");
752 strcpy(rcfile, user_homedir);
753 PATH_CONCAT(rcfile, PLOTRC);
754 plotrc = fopen(rcfile, "r");
756 #if defined(ATARI) || defined(MTOS)
757 if (plotrc == NULL) {
758 char const *const ext[] = { NULL };
759 char *ini_ptr = findfile(PLOTRC, user_gnuplotpath, ext);
762 plotrc = fopen(ini_ptr, "r");
764 #endif /* ATARI || MTOS */
768 load_file(plotrc, (rcfile==NULL) ? PLOTRC : rcfile, FALSE);
769 push_terminal(0); /* needed if terminal or its options were changed */
778 if (user_homedir == NULL) {
779 const char *env_home;
781 if ((env_home = getenv(HOME))
783 || (env_home = appdata_directory())
784 || (env_home = getenv("USERPROFILE"))
787 || (env_home = getenv("HOME"))
790 user_homedir = (const char *) gp_strdup(env_home);
791 else if (interactive)
792 int_warn(NO_CARET, "no HOME found");
794 /* Hhm ... what about VMS? */
795 if (user_shell == NULL) {
796 const char *env_shell;
798 if ((env_shell = getenv("SHELL")) == NULL)
799 #if defined(MSDOS) || defined(_Windows) || defined(DOS386) || defined(OS2)
800 if ((env_shell = getenv("COMSPEC")) == NULL)
804 user_shell = (const char *) gp_strdup(env_shell);
806 #if defined(ATARI) || defined(MTOS)
807 if (user_gnuplotpath == NULL) {
810 if (env_gpp = getenv("GNUPLOTPATH"))
811 user_gnuplotpath = (const char *) gp_strdup(env_gpp);
816 /* expand tilde in path
817 * path cannot be a static array!
818 * tilde must be the first character in *pathp;
819 * we may change that later
822 gp_expand_tilde(char **pathp)
825 int_error(NO_CARET, "Cannot expand empty path");
827 if ((*pathp)[0] == '~' && (*pathp)[1] == DIRSEP1) {
829 size_t n = strlen(*pathp);
831 *pathp = gp_realloc(*pathp, n + strlen(user_homedir), "tilde expansion");
832 /* include null at the end ... */
833 memmove(*pathp + strlen(user_homedir) - 1, *pathp, n + 1);
834 memcpy(*pathp, user_homedir, strlen(user_homedir));
836 int_warn(NO_CARET, "HOME not set - cannot expand tilde");
845 extend_token_table();
846 replot_line = gp_alloc(1, "string");
854 ExecuteMacro(char *argv, int namelength)
859 char pszName[CCHMAXPATH];
864 if (namelength >= sizeof(pszName))
866 /* FIXME HBB 20010121: 3rd argument doesn't make sense. Either
867 * this should be sizeof(pszName), or it shouldn't use
868 * safe_strncpy(), here */
869 safe_strncpy(pszName, argv, namelength + 1);
870 rxArgStr = &argv[namelength];
871 RXSTRPTR(rxRc) = NULL;
875 C-like calling of function: program name is first
877 In REXX you would have to use
878 Parse Arg param0, param1
879 to get the program name in param0 and the arguments in param1.
881 Some versions before gnuplot 3.7pl1 used a similar approach but
882 passed program name and arguments in a single string:
883 (==> Parse Arg param0 param1)
886 MAKERXSTRING(rxArg[0], pszName, strlen(pszName));
889 MAKERXSTRING(rxArg[1], rxArgStr, strlen(rxArgStr));
894 REXX standard calling (gnuplot 3.7pl1 and above):
895 The program name is not supplied and so all actual arguments
896 are in a single string:
898 We even handle blanks like cmd.exe when calling REXX programs.
902 MAKERXSTRING(rxArg[0], rxArgStr, strlen(rxArgStr));
918 CallFromRexx = FALSE;
920 /* am: a word WRT errors codes:
921 the negative ones don't seem to have symbolic names, you can get
922 them from the OREXX reference, they're not in REXX Programming Guide -
923 no idea where to retrieve them from a Warp 3 reference ??
924 The positive ones are somehow referenced in REXXPG
929 /* Interpreter couldn't be started */
931 /* run was cancelled, but don't give error message */
937 /* We don't we try to use rxRc ?
938 BTW, don't use free() instead since it's allocated inside RexxStart()
939 and not in our executable using the EMX libraries */
941 /* I guess it's NULL if something major went wrong,
942 NULL strings are usually not part of the REXX language ... */
943 DosFreeMem(rxRc.strptr);
948 /* Rexx command line interface */
950 RexxInterface(PRXSTRING rxCmd, PUSHORT pusErr, PRXSTRING rxRc)
953 static JMP_BUF keepenv;
956 memcpy(keepenv, command_line_env, sizeof(JMP_BUF));
957 if (!SETJMP(command_line_env, 1)) {
958 /* Set variable gp_input_line.
959 Watch out for line length of NOT_ZERO_TERMINATED strings ! */
960 cmdlen = rxCmd->strlength + 1;
961 /* FIXME HBB 20010121: 3rd argument doesn't make sense. Either
962 * this should be gp_input_line_len, or it shouldn't use
963 * safe_strncpy(), here */
964 safe_strncpy(gp_input_line, rxCmd->strptr, cmdlen);
965 gp_input_line[cmdlen] = NUL;
967 *pusErr = RXSUBCOM_OK;
968 rxRc->strptr[0] = rc + '0';
969 rxRc->strptr[1] = NUL;
970 rxRc->strlength = strlen(rxRc->strptr);
973 We end up here when bail_to_command_line() is called.
974 Therefore sometimes this call should be avoided when
975 executing a REXX program (e.g. 'Cancel' from
976 PM GUI after a 'pause -1' command)
978 *pusErr = RXSUBCOM_ERROR;
979 RexxSetHalt(getpid(), 1);
981 memcpy(command_line_env, keepenv, sizeof(JMP_BUF));
986 #ifdef GNUPLOT_HISTORY
987 # if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)
990 wrapper_for_write_history()
993 /* Alternative code, saves one disk access */
994 if (history_is_stifled())
996 if (gnuplot_history_size >= 0)
997 stifle_history (gnuplot_history_size);
999 /* returns 0 on success */
1000 if (write_history(expanded_history_filename))
1001 fprintf (stderr, "Warning: Could not write history file!!!\n");
1005 /* if writing was successful, truncate history
1006 * to gnuplot_history_size lines
1008 if (write_history(expanded_history_filename)) {
1009 if (gnuplot_history_size >= 0)
1010 history_truncate_file(expanded_history_filename, gnuplot_history_size);
1015 # else /* HAVE_LIBREADLINE || HAVE_LIBEDITLINE */
1017 /* version for gnuplot's own write_history */
1019 wrapper_for_write_history()
1021 /* What we really want to do is truncate(expanded_history_filename),
1022 but this is only available on BSD compatible systems */
1023 remove(expanded_history_filename);
1024 if (gnuplot_history_size < 0)
1025 write_history(expanded_history_filename);
1027 write_history_n(gnuplot_history_size, expanded_history_filename, "w");
1030 # endif /* HAVE_LIBREADLINE || HAVE_LIBEDITLINE */
1031 #endif /* GNUPLOT_HISTORY */