Annotation of OpenXM_contrib/gnuplot/plot.c, Revision 1.1.1.2
1.1 maekawa 1: #ifndef lint
1.1.1.2 ! maekawa 2: static char *RCSid = "$Id: plot.c,v 1.18.2.2 1999/09/23 13:26:36 lhecking Exp $";
1.1 maekawa 3: #endif
4:
5: /* GNUPLOT - plot.c */
6:
7: /*[
8: * Copyright 1986 - 1993, 1998 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 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,
20: * provided you
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
28: * software.
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.
32: *
33: * This software is provided "as is" without express or implied warranty
34: * to the extent permitted by applicable law.
35: ]*/
36:
37: #include <signal.h>
38:
39: #include "plot.h"
40: #include "fit.h"
41: #include "setshow.h"
42: #include "fnproto.h"
43: #include <setjmp.h>
44:
45: #if defined(MSDOS) || defined(DOS386) || defined(__EMX__)
46: # include <io.h>
47: #endif
48:
49: /* HBB: for the control87 function, if used with DJGPP V1: */
50: #if defined(DJGPP) && (DJGPP!=2)
51: # include "ctrl87.h"
52: #endif
53:
54: #ifdef VMS
55: # ifndef __GNUC__
56: # include <unixio.h>
57: # endif
58: # include <smgdef.h>
59: extern int vms_vkid;
60: extern smg$create_virtual_keyboard();
61: extern int vms_ktid;
62: extern smg$create_key_table();
63: #endif /* VMS */
64:
65: #ifdef AMIGA_SC_6_1
66: # include <proto/dos.h>
67: #endif
68:
69: #ifdef _Windows
70: # include <windows.h>
71: # ifndef SIGINT
72: # define SIGINT 2 /* for MSC */
73: # endif
74: #endif /* _Windows */
75:
76: extern FILE *gpoutfile;
77:
78: TBOOLEAN interactive = TRUE; /* FALSE if stdin not a terminal */
79: TBOOLEAN noinputfiles = TRUE; /* FALSE if there are script files */
80:
81: /* these 2 could be in misc.c, but are here with all the other globals */
82: TBOOLEAN do_load_arg_substitution = FALSE;
83: char *call_args[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
84:
85: char *infile_name = NULL; /* name of command file; NULL if terminal */
86:
1.1.1.2 ! maekawa 87: #ifdef HAVE_LIBREADLINE
1.1 maekawa 88: extern char *rl_readline_name;
89: extern int rl_complete_with_tilde_expansion;
90: #endif
91:
92: #ifdef X11
93: extern int X11_args __PROTO((int, char **));
94: #endif
95:
96: /* patch to get home dir, see command.c */
97: #if (defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))) || defined(DJGPP)
98: # include <dir.h> /* MAXPATH */
99: char HelpFile[MAXPATH];
100: #endif /* - DJL */
101:
102: #ifndef STDOUT
103: # define STDOUT 1
104: #endif
105:
106: /* a longjmp buffer to get back to the command line */
107: #ifdef _Windows
108: static jmp_buf far command_line_env;
109: #else
110: static jmp_buf command_line_env;
111: #endif
112:
113: static void load_rcfile __PROTO((void));
114: RETSIGTYPE inter __PROTO((int anint));
115:
116: /* built-in function table */
117: struct ft_entry GPFAR ft[] =
118: {
119: /* internal functions: */
120: {"push", (FUNC_PTR) f_push},
121: {"pushc", (FUNC_PTR) f_pushc},
122: {"pushd1", (FUNC_PTR) f_pushd1},
123: {"pushd2", (FUNC_PTR) f_pushd2},
124: {"pushd", (FUNC_PTR) f_pushd},
125: {"call", (FUNC_PTR) f_call},
126: {"calln", (FUNC_PTR) f_calln},
127: {"lnot", (FUNC_PTR) f_lnot},
128: {"bnot", (FUNC_PTR) f_bnot},
129: {"uminus", (FUNC_PTR) f_uminus},
130: {"lor", (FUNC_PTR) f_lor},
131: {"land", (FUNC_PTR) f_land},
132: {"bor", (FUNC_PTR) f_bor},
133: {"xor", (FUNC_PTR) f_xor},
134: {"band", (FUNC_PTR) f_band},
135: {"eq", (FUNC_PTR) f_eq},
136: {"ne", (FUNC_PTR) f_ne},
137: {"gt", (FUNC_PTR) f_gt},
138: {"lt", (FUNC_PTR) f_lt},
139: {"ge", (FUNC_PTR) f_ge},
140: {"le", (FUNC_PTR) f_le},
141: {"plus", (FUNC_PTR) f_plus},
142: {"minus", (FUNC_PTR) f_minus},
143: {"mult", (FUNC_PTR) f_mult},
144: {"div", (FUNC_PTR) f_div},
145: {"mod", (FUNC_PTR) f_mod},
146: {"power", (FUNC_PTR) f_power},
147: {"factorial", (FUNC_PTR) f_factorial},
148: {"bool", (FUNC_PTR) f_bool},
149: {"dollars", (FUNC_PTR) f_dollars}, /* for using extension */
150: {"jump", (FUNC_PTR) f_jump},
151: {"jumpz", (FUNC_PTR) f_jumpz},
152: {"jumpnz", (FUNC_PTR) f_jumpnz},
153: {"jtern", (FUNC_PTR) f_jtern},
154:
155: /* standard functions: */
156: {"real", (FUNC_PTR) f_real},
157: {"imag", (FUNC_PTR) f_imag},
158: {"arg", (FUNC_PTR) f_arg},
159: {"conjg", (FUNC_PTR) f_conjg},
160: {"sin", (FUNC_PTR) f_sin},
161: {"cos", (FUNC_PTR) f_cos},
162: {"tan", (FUNC_PTR) f_tan},
163: {"asin", (FUNC_PTR) f_asin},
164: {"acos", (FUNC_PTR) f_acos},
165: {"atan", (FUNC_PTR) f_atan},
166: {"atan2", (FUNC_PTR) f_atan2},
167: {"sinh", (FUNC_PTR) f_sinh},
168: {"cosh", (FUNC_PTR) f_cosh},
169: {"tanh", (FUNC_PTR) f_tanh},
170: {"int", (FUNC_PTR) f_int},
171: {"abs", (FUNC_PTR) f_abs},
172: {"sgn", (FUNC_PTR) f_sgn},
173: {"sqrt", (FUNC_PTR) f_sqrt},
174: {"exp", (FUNC_PTR) f_exp},
175: {"log10", (FUNC_PTR) f_log10},
176: {"log", (FUNC_PTR) f_log},
177: {"besj0", (FUNC_PTR) f_besj0},
178: {"besj1", (FUNC_PTR) f_besj1},
179: {"besy0", (FUNC_PTR) f_besy0},
180: {"besy1", (FUNC_PTR) f_besy1},
181: {"erf", (FUNC_PTR) f_erf},
182: {"erfc", (FUNC_PTR) f_erfc},
183: {"gamma", (FUNC_PTR) f_gamma},
184: {"lgamma", (FUNC_PTR) f_lgamma},
185: {"ibeta", (FUNC_PTR) f_ibeta},
186: {"igamma", (FUNC_PTR) f_igamma},
187: {"rand", (FUNC_PTR) f_rand},
188: {"floor", (FUNC_PTR) f_floor},
189: {"ceil", (FUNC_PTR) f_ceil},
190:
191: {"norm", (FUNC_PTR) f_normal}, /* XXX-JG */
192: {"inverf", (FUNC_PTR) f_inverse_erf}, /* XXX-JG */
193: {"invnorm", (FUNC_PTR) f_inverse_normal}, /* XXX-JG */
194: {"asinh", (FUNC_PTR) f_asinh},
195: {"acosh", (FUNC_PTR) f_acosh},
196: {"atanh", (FUNC_PTR) f_atanh},
197:
198: {"column", (FUNC_PTR) f_column}, /* for using */
199: {"valid", (FUNC_PTR) f_valid}, /* for using */
200: {"timecolumn", (FUNC_PTR) f_timecolumn}, /* for using */
201:
202: {"tm_sec", (FUNC_PTR) f_tmsec}, /* for timeseries */
203: {"tm_min", (FUNC_PTR) f_tmmin}, /* for timeseries */
204: {"tm_hour", (FUNC_PTR) f_tmhour}, /* for timeseries */
205: {"tm_mday", (FUNC_PTR) f_tmmday}, /* for timeseries */
206: {"tm_mon", (FUNC_PTR) f_tmmon}, /* for timeseries */
207: {"tm_year", (FUNC_PTR) f_tmyear}, /* for timeseries */
208: {"tm_wday", (FUNC_PTR) f_tmwday}, /* for timeseries */
209: {"tm_yday", (FUNC_PTR) f_tmyday}, /* for timeseries */
210:
211: {NULL, NULL}
212: };
213:
214: static struct udvt_entry udv_pi = { NULL, "pi", FALSE };
215: /* first in linked list */
216: struct udvt_entry *first_udv = &udv_pi;
217: struct udft_entry *first_udf = NULL;
218:
1.1.1.2 ! maekawa 219: static int exit_status = EXIT_SUCCESS;
! 220:
1.1 maekawa 221: #ifdef OS2
222: # define INCL_DOS
223: # define INCL_REXXSAA
224: # include <os2.h>
225: # include <process.h>
226: ULONG RexxInterface(PRXSTRING, PUSHORT, PRXSTRING);
227: int ExecuteMacro(char *, int);
228: void PM_intc_cleanup();
229: void PM_setup();
230: #endif /* OS2 */
231:
232: #if defined(ATARI) || defined(MTOS)
233: /* For findfile () (?) */
234: # include <support.h>
235: void appl_exit(void);
236: void MTOS_open_pipe(void);
237: extern int aesid;
238: #endif
239:
240: RETSIGTYPE inter(anint)
241: int anint;
242: {
243: #ifdef OS2
244: (void) signal(anint, SIG_ACK);
245: #else
246: (void) signal(SIGINT, (sigfunc) inter);
247: #endif
248:
249: #ifndef DOSX286
250: (void) signal(SIGFPE, SIG_DFL); /* turn off FPE trapping */
251: #endif
252: #ifdef OS2
253: PM_intc_cleanup();
254: #else
255: term_reset();
256: (void) putc('\n', stderr);
257: longjmp(command_line_env, TRUE); /* return to prompt */
258: #endif
259: }
260:
1.1.1.2 ! maekawa 261: #ifdef LINUXVGA
! 262: /* utility functions to ensure that setuid gnuplot
! 263: * assumes root privileges only for those parts
! 264: * of the code which require root rights.
! 265: *
! 266: * By "Dr. Werner Fink" <werner@suse.de>
! 267: */
! 268: static uid_t euid, ruid;
! 269: static gid_t egid, rgid;
! 270: static int asked_privi = 0;
! 271:
! 272: void
! 273: drop_privilege()
! 274: {
! 275: if (!asked_privi) {
! 276: euid = geteuid();
! 277: egid = getegid();
! 278: ruid = getuid();
! 279: rgid = getgid();
! 280: asked_privi = 1;
! 281: }
! 282: if (setegid(rgid) == -1)
! 283: (void) fprintf(stderr, "setegid(%d): %s\n",
! 284: (int) rgid, strerror(errno));
! 285: if (seteuid(ruid) == -1)
! 286: (void) fprintf(stderr, "seteuid(%d): %s\n",
! 287: (int) ruid, strerror(errno));
! 288: }
! 289:
! 290: void
! 291: take_privilege()
! 292: {
! 293: if (!asked_privi) {
! 294: euid = geteuid();
! 295: egid = getegid();
! 296: ruid = getuid();
! 297: rgid = getgid();
! 298: asked_privi = 1;
! 299: }
! 300: if (setegid(egid) == -1)
! 301: (void) fprintf(stderr, "setegid(%d): %s\n",
! 302: (int) egid, strerror(errno));
! 303: if (seteuid(euid) == -1)
! 304: (void) fprintf(stderr, "seteuid(%d): %s\n",
! 305: (int) euid, strerror(errno));
! 306: }
! 307: #endif /* LINUXVGA */
! 308:
1.1 maekawa 309:
310: /* a wrapper for longjmp so we can keep everything local */
311: void bail_to_command_line()
312: {
313: longjmp(command_line_env, TRUE);
314: }
315:
316: #if defined(_Windows) || defined(_Macintosh)
317: int gnu_main(argc, argv)
318: #else
319: int main(argc, argv)
320: #endif
321: int argc;
322: char **argv;
323: {
324: #ifdef LINUXVGA
325: LINUX_setup();
326: #endif
327: /* make sure that we really have revoked root access, this might happen if
328: gnuplot is compiled without vga support but is installed suid by mistake */
329: #ifdef __linux__
330: setuid(getuid());
331: #endif
332: #if defined(MSDOS) && !defined(_Windows) && !defined(__GNUC__)
333: PC_setup();
334: #endif /* MSDOS !Windows */
335: /* HBB: Seems this isn't needed any more for DJGPP V2? */
336: /* HBB: disable all floating point exceptions, just keep running... */
337: #if defined(DJGPP) && (DJGPP!=2)
338: _control87(MCW_EM, MCW_EM);
339: #endif
340:
341: #if defined(OS2)
342: int rc;
343: if (_osmode == OS2_MODE) {
344: PM_setup();
345: rc = RexxRegisterSubcomExe("GNUPLOT", (PFN) RexxInterface, NULL);
346: }
347: #endif
348:
349: /* malloc large blocks, otherwise problems with fragmented mem */
350: #ifdef OSK
351: _mallocmin(102400);
352: #endif
353:
354: #ifdef MALLOCDEBUG
355: malloc_debug(7);
356: #endif
357:
358: /* get helpfile from home directory */
359: #ifndef DOSX286
360: # ifndef _Windows
361: # if defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))
362: strcpy(HelpFile, argv[0]);
363: strcpy(strrchr(HelpFile, DIRSEP1), "\\gnuplot.gih");
364: # endif /* - DJL */
365: # endif /* !_Windows */
366: #endif /* !DOSX286 */
367: #ifdef __DJGPP__
368: {
369: char *s;
370: strcpy(HelpFile, argv[0]);
371: for (s = HelpFile; *s; s++)
372: if (*s == DIRSEP1)
373: *s = DIRSEP2; /* '\\' to '/' */
374: strcpy(strrchr(HelpFile, DIRSEP2), "/gnuplot.gih");
375: } /* Add also some "paranoid" tests for '\\': AP */
376: #endif /* DJGPP */
377:
378: #ifdef VMS
379: unsigned int status[2] = { 1, 0 };
380: #endif
381:
1.1.1.2 ! maekawa 382: #ifdef HAVE_LIBREADLINE
1.1 maekawa 383: rl_readline_name = argv[0];
384: rl_complete_with_tilde_expansion = 1;
385: #endif
386:
387: #ifdef X11
388: {
389: int n = X11_args(argc, argv);
390: argv += n;
391: argc -= n;
392: }
393: #endif
394:
395: #ifdef apollo
396: apollo_pfm_catch();
397: #endif
398:
399: /* moved to ATARI_init in atariaes.trm */
400: /* #ifdef ATARI
401: void application_init(void);
402: application_init();
403: #endif */
404:
405: #ifdef MTOS
406: MTOS_open_pipe();
407: #endif
408:
409: setbuf(stderr, (char *) NULL);
410:
411: #ifndef NO_SETVBUF
412: /* this was once setlinebuf(). Docs say this is
413: * identical to setvbuf(,NULL,_IOLBF,0), but MS C
414: * faults this (size out of range), so we try with
415: * size of 1024 instead. [SAS/C does that, too. -lh]
416: * Failing this, I propose we just make the call and
417: * ignore the return : its probably not a big deal
418: */
419: if (setvbuf(stdout, (char *) NULL, _IOLBF, (size_t) 1024) != 0)
420: fputs("Could not linebuffer stdout\n", stderr);
421: #endif
422:
423: gpoutfile = stdout;
424: (void) Gcomplex(&udv_pi.udv_value, Pi, 0.0);
425:
426: init_memory();
427:
428: interactive = FALSE;
429: init_terminal(); /* can set term type if it likes */
430:
431: #ifdef AMIGA_SC_6_1
432: if (IsInteractive(Input()) == DOSTRUE)
433: interactive = TRUE;
434: else
435: interactive = FALSE;
436: #else
437: # if (defined(__MSC__) && defined(_Windows)) || defined(__WIN32__)
438: interactive = TRUE;
439: # else
440: interactive = isatty(fileno(stdin));
441: # endif
442: #endif /* !AMIGA_SC_6_1 */
443:
444: if (argc > 1)
445: interactive = noinputfiles = FALSE;
446: else
447: noinputfiles = TRUE;
448:
449: if (interactive)
450: show_version(stderr);
451:
452: #ifdef VMS
453: /* initialise screen management routines for command recall */
454: if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
455: done(status[1]);
456: if (status[1] = smg$create_key_table(&vms_ktid) != SS$_NORMAL)
457: done(status[1]);
458: #endif /* VMS */
459:
460: if (!setjmp(command_line_env)) {
461: /* first time */
462: interrupt_setup();
463: load_rcfile();
464: init_fit(); /* Initialization of fitting module */
465:
466: if (interactive && term != 0) /* not unknown */
467: fprintf(stderr, "\nTerminal type set to '%s'\n", term->name);
468: } else {
469: /* come back here from int_error() */
1.1.1.2 ! maekawa 470: if (interactive == FALSE)
! 471: exit_status = EXIT_FAILURE;
! 472:
1.1 maekawa 473: #ifdef AMIGA_SC_6_1
474: (void) rawcon(0);
475: #endif
476: load_file_error(); /* if we were in load_file(), cleanup */
477: #ifdef _Windows
478: SetCursor(LoadCursor((HINSTANCE) NULL, IDC_ARROW));
479: #endif
480:
481: #ifdef VMS
482: /* after catching interrupt */
483: /* VAX stuffs up stdout on SIGINT while writing to stdout,
484: so reopen stdout. */
485: if (gpoutfile == stdout) {
486: if ((stdout = freopen("SYS$OUTPUT", "w", stdout)) == NULL) {
487: /* couldn't reopen it so try opening it instead */
488: if ((stdout = fopen("SYS$OUTPUT", "w")) == NULL) {
489: /* don't use int_error here - causes infinite loop! */
490: fputs("Error opening SYS$OUTPUT as stdout\n", stderr);
491: }
492: }
493: gpoutfile = stdout;
494: }
495: #endif /* VMS */
496: if (!interactive && !noinputfiles) {
497: term_reset();
498: #if defined(ATARI) || defined(MTOS)
499: if (aesid > -1)
500: atexit(appl_exit);
501: #endif
502: return (IO_ERROR); /* exit on non-interactive error */
503: }
504: }
505:
506: if (argc > 1) {
507: #ifdef _Windows
508: int noend = 0;
509: #endif
510:
511: /* load filenames given as arguments */
512: while (--argc > 0) {
513: ++argv;
514: c_token = NO_CARET; /* in case of file not found */
515: #ifdef _Windows
516: if (stricmp(*argv, "-noend") == 0 || stricmp(*argv, "/noend") == 0)
517: noend = 1;
518: else
519: #endif
520: if (strcmp(*argv, "-") == 0) {
521: /* DBT 10-7-98 go interactive if "-" on command line */
522:
523: interactive = TRUE;
524: /* will this work on all platforms? */
525:
526: while (!com_line());
527:
1.1.1.2 ! maekawa 528: /* interactive = FALSE; */ /* should this be here? */
1.1 maekawa 529:
530: } else
531: load_file(fopen(*argv, "r"), *argv, FALSE);
532: }
533: #ifdef _Windows
534: if (noend) {
535: interactive = TRUE;
536: while (!com_line());
537: }
538: #endif
539: } else {
540: /* take commands from stdin */
541: while (!com_line());
542: }
543:
544: term_reset();
545:
546: #ifdef OS2
547: if (_osmode == OS2_MODE)
548: RexxDeregisterSubcom("GNUPLOT", NULL);
549: #endif
550:
551: #if defined(ATARI) || defined(MTOS)
552: if (aesid > -1)
553: atexit(appl_exit);
554: #endif
1.1.1.2 ! maekawa 555: return (exit_status);
1.1 maekawa 556: }
557:
558: #if (defined(ATARI) || defined(MTOS)) && defined(__PUREC__)
559: int purec_matherr(struct exception *e)
560: {
561: char *c;
562: switch (e->type) {
563: case DOMAIN:
564: c = "domain error";
565: break;
566: case SING:
567: c = "argument singularity";
568: break;
569: case OVERFLOW:
570: c = "overflow range";
571: break;
572: case UNDERFLOW:
573: c = "underflow range";
574: break;
575: default:
576: c = "(unknown error";
577: break;
578: }
579: fprintf(stderr, "\
580: math exception : %s\n\
581: name : %s\n\
582: arg 1: %e\n\
583: arg 2: %e\n\
584: ret : %e\n",
585: c,
586: e->name,
587: e->arg1,
588: e->arg2,
589: e->retval);
590:
591: return 1;
592: }
593: #endif /* (ATARI || MTOS) && PUREC */
594:
595:
596: /* Set up to catch interrupts */
597: void interrupt_setup()
598: {
599: #ifdef __PUREC__
600: setmatherr(purec_matherr);
601: #endif
602:
603: (void) signal(SIGINT, (sigfunc) inter);
604:
605: #ifdef SIGPIPE
606: /* ignore pipe errors, this might happen with set output "|head" */
607: (void) signal(SIGPIPE, SIG_IGN);
608: #endif /* SIGPIPE */
609: }
610:
611:
612: /* Look for a gnuplot init file in . or home directory */
613: static void load_rcfile()
614: {
615: FILE *plotrc = NULL;
616: char home[80];
617: char rcfile[sizeof(PLOTRC) + 80];
618: char *tmp_home = NULL;
619: #ifndef VMS
620: char *p; /* points to last char in home path, or to \0, if none */
621:
622: tmp_home = getenv(HOME);
623: if (tmp_home) {
624: safe_strncpy(home, tmp_home, sizeof(home));
625: if (strlen(home))
626: p = &home[strlen(home) - 1];
627: else
628: p = home;
629: if ((*p != DIRSEP1) && (*p != DIRSEP2) && (*p != NUL)) {
630: assert(p >= home && p <= (home + sizeof(home) - 1 - 2));
631: if (*p)
632: p++;
633: *p++ = DIRSEP1;
634: *p = NUL;
635: }
636: }
637: #else /* VMS */
638: safe_strncpy(home, HOME, sizeof(home));
639: tmp_home = home;
640: #endif /* VMS */
641:
642: #ifdef NOCWDRC
643: /* inhibit check of init file in current directory for security reasons */
644: #else
645: (void) strcpy(rcfile, PLOTRC);
646: plotrc = fopen(rcfile, "r");
647: #endif /* !NOCWDRC */
648:
649: if (plotrc == NULL) {
650: if (tmp_home) {
651: (void) sprintf(rcfile, "%s%s", home, PLOTRC);
652: plotrc = fopen(rcfile, "r");
653: #if defined(ATARI) || defined(MTOS)
654: if (plotrc == NULL) {
655: char const *const ext[] = { NULL };
656: char *ini_ptr = findfile(PLOTRC, getenv("GNUPLOTPATH"), ext);
657:
658: if (ini_ptr)
659: plotrc = fopen(ini_ptr, "r");
660: }
661: #endif /* ATARI || MTOS */
662: }
663: }
664: if (plotrc)
665: load_file(plotrc, rcfile, FALSE);
666: }
667:
668: #ifdef OS2
669:
670: int ExecuteMacro(char *argv, int namelength)
671: {
672: RXSTRING rxRc;
673: RXSTRING rxArg;
674: char pszName[CCHMAXPATH];
675: short sRc;
676: int rc;
677:
678: safe_strncpy(pszName, argv, sizeof(pszName));
679: MAKERXSTRING(rxArg, argv, strlen(argv));
680: rc = RexxStart(1,
681: &rxArg,
682: pszName,
683: NULL,
684: "GNUPLOT",
685: RXCOMMAND,
686: NULL,
687: &sRc,
688: &rxRc);
689: if (rc == -4)
690: rc = 0; /* run was cancelled-don't give error message */
691:
692: /* We don't use this value ?
693: BTW, don't use free() instead since it's allocated inside RexxStart() */
694: DosFreeMem(rxRc.strptr);
695: return rc;
696: }
697:
698: ULONG RexxInterface(PRXSTRING rxCmd, PUSHORT pusErr, PRXSTRING rxRc)
699: /*
700: ** Rexx command line interface
701: */
702: {
703: int rc;
704: static jmp_buf keepenv;
705: int cmdlen;
706:
707: memcpy(keepenv, command_line_env, sizeof(jmp_buf));
708: if (!setjmp(command_line_env)) {
709: /* set variable input_line.
710: * Watch out for line length of NOT_ZERO_TERMINATED strings ! */
711: cmdlen = rxCmd->strlength + 1;
712: safe_strncpy(input_line, rxCmd->strptr, cmdlen);
713: input_line[cmdlen] = NUL;
714:
715: rc = do_line();
716: *pusErr = RXSUBCOM_OK;
717: rxRc->strptr[0] = rc + '0';
718: rxRc->strptr[1] = NUL;
719: rxRc->strlength = strlen(rxRc->strptr);
720: } else {
721: *pusErr = RXSUBCOM_ERROR;
722: RexxSetHalt(getpid(), 1);
723: }
724: memcpy(command_line_env, keepenv, sizeof(jmp_buf));
725: return 0;
726: }
727: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>