Annotation of OpenXM_contrib/gnuplot/command.c, Revision 1.1.1.1
1.1 maekawa 1: #ifndef lint
2: static char *RCSid = "$Id: command.c,v 1.126 1998/06/22 12:24:48 ddenholm Exp $";
3: #endif
4:
5: /* GNUPLOT - command.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: /*
38: * Changes:
39: *
40: * Feb 5, 1992 Jack Veenstra (veenstra@cs.rochester.edu) Added support to
41: * filter data values read from a file through a user-defined function before
42: * plotting. The keyword "thru" was added to the "plot" command. Example
43: * syntax: f(x) = x / 100 plot "test.data" thru f(x) This example divides all
44: * the y values by 100 before plotting. The filter function processes the
45: * data before any log-scaling occurs. This capability should be generalized
46: * to filter x values as well and a similar feature should be added to the
47: * "splot" command.
48: *
49: * 19 September 1992 Lawrence Crowl (crowl@cs.orst.edu)
50: * Added user-specified bases for log scaling.
51: */
52:
53: #include "plot.h"
54: #include "setshow.h"
55: #include "fit.h"
56: #include "binary.h"
57:
58: #if defined(MSDOS) || defined(DOS386)
59: # ifdef DJGPP
60: extern char HelpFile[]; /* patch for do_help - AP */
61: # endif /* DJGPP */
62: # ifdef __TURBOC__
63: # ifndef _Windows
64: extern unsigned _stklen = 16394; /* increase stack size */
65: extern char HelpFile[]; /* patch for do_help - DJL */
66: # endif /* _Windows */
67: # endif /* TURBOC */
68: #endif /* MSDOS */
69:
70: #ifndef _Windows
71: # include "help.h"
72: #else
73: static int winsystem __PROTO((char *));
74: #endif /* _Windows */
75:
76: #ifndef STDOUT
77: # define STDOUT 1
78: #endif
79:
80: #ifdef _Windows
81: # include <windows.h>
82: # ifdef __MSC__
83: # include <malloc.h>
84: # else
85: # include <alloc.h>
86: # include <dir.h> /* setdisk() */
87: # endif /* !MSC */
88: # include "win/wgnuplib.h"
89: extern TW textwin;
90: extern LPSTR winhelpname;
91: extern void screen_dump(void); /* in term/win.trm */
92: extern int Pause(LPSTR mess); /* in winmain.c */
93: #endif /* _Windows */
94:
95: #ifdef _Windows
96: # define SET_CURSOR_WAIT SetCursor(LoadCursor((HINSTANCE) NULL, IDC_WAIT))
97: # define SET_CURSOR_ARROW SetCursor(LoadCursor((HINSTANCE) NULL, IDC_ARROW))
98: #else
99: # define SET_CURSOR_WAIT /* nought, zilch */
100: # define SET_CURSOR_ARROW /* nought, zilch */
101: #endif
102:
103: #ifdef OS2
104: /* emx has getcwd, chdir that can handle drive names */
105: # define chdir _chdir2
106: extern int PM_pause(char *); /* term/pm.trm */
107: extern int ExecuteMacro(char *, int); /* plot.c */
108: #endif /* OS2 */
109:
110: #ifdef VMS
111: int vms_vkid; /* Virtual keyboard id */
112: int vms_ktid; /* key table id, for translating keystrokes */
113: #endif /* VMS */
114:
115: /* Used by vws.trm */
116: void replotrequest __PROTO((void));
117:
118:
119: /* static prototypes */
120: static int command __PROTO((void));
121: static int read_line __PROTO((char *prompt));
122: static void do_shell __PROTO((void));
123: static void do_help __PROTO((int toplevel));
124: static void do_system __PROTO((void));
125: static int changedir __PROTO((char *path));
126:
127: /* input data, parsing variables */
128: #ifdef AMIGA_SC_6_1
129: __far int num_tokens, c_token;
130: #else
131: int num_tokens, c_token;
132: #endif
133:
134: struct lexical_unit *token;
135: int token_table_size;
136:
137: char *input_line;
138: int input_line_len;
139: int inline_num; /* input line number */
140:
141: struct udft_entry *dummy_func; /* NULL means no dummy vars active */
142:
143: char c_dummy_var[MAX_NUM_VAR][MAX_ID_LEN+1]; /* current dummy vars */
144:
145:
146: /* support for replot command */
147: char *replot_line;
148: int plot_token; /* start of 'plot' command */
149:
150: /* If last plot was a 3d one. */
151: TBOOLEAN is_3d_plot = FALSE;
152:
153: #define Inc_c_token if (++c_token >= num_tokens) \
154: int_error ("Syntax error", c_token);
155:
156: /* support for dynamic size of input line */
157: void extend_input_line()
158: {
159: if (input_line_len == 0) {
160: /* first time */
161: input_line = gp_alloc(MAX_LINE_LEN, "input_line");
162: input_line_len = MAX_LINE_LEN;
163: input_line[0] = NUL;
164: } else {
165: input_line = gp_realloc(input_line, input_line_len + MAX_LINE_LEN, "extend input line");
166: input_line_len += MAX_LINE_LEN;
167: FPRINTF((stderr, "extending input line to %d chars\n", input_line_len));
168: }
169: }
170:
171:
172: void extend_token_table()
173: {
174: if (token_table_size == 0) {
175: /* first time */
176: token = (struct lexical_unit *) gp_alloc(MAX_TOKENS * sizeof(struct lexical_unit), "token table");
177: token_table_size = MAX_TOKENS;
178: } else {
179: token = gp_realloc(token, (token_table_size + MAX_TOKENS) * sizeof(struct lexical_unit), "extend token table");
180: token_table_size += MAX_TOKENS;
181: FPRINTF((stderr, "extending token table to %d elements\n", token_table_size));
182: }
183: }
184:
185:
186: void init_memory()
187: {
188: extend_input_line();
189: extend_token_table();
190: replot_line = gp_alloc(1, "string");
191: *replot_line = NUL;
192: }
193:
194:
195: int com_line()
196: {
197: if (multiplot) {
198: /* calls int_error() if it is not happy */
199: term_check_multiplot_okay(interactive);
200:
201: if (read_line("multiplot> "))
202: return (1);
203: } else {
204: if (read_line(PROMPT))
205: return (1);
206: }
207:
208: /* So we can flag any new output: if false at time of error,
209: * we reprint the command line before printing caret.
210: * TRUE for interactive terminals, since the command line is typed.
211: * FALSE for non-terminal stdin, so command line is printed anyway.
212: * (DFK 11/89)
213: */
214: screen_ok = interactive;
215:
216: if (do_line())
217: return (1);
218: else
219: return (0);
220: }
221:
222:
223: int do_line()
224: {
225: /* Line continuation has already been handled
226: * by read_line() */
227: char *inlptr = input_line;
228:
229: /* Skip leading whitespace */
230: while (isspace((int)*inlptr))
231: inlptr++;
232:
233: if (inlptr != input_line) {
234: /* If there was leading whitespace, copy the actual
235: * command string to the front. use memmove() because
236: * source and target overlap */
237: memmove(input_line,inlptr,strlen(inlptr));
238: /* Terminate resulting string */
239: input_line[strlen(inlptr)] = NUL;
240: }
241:
242: FPRINTF((stderr, "Input line: \"%s\"\n",input_line));
243:
244: /* also used in load_file */
245: if (is_system(input_line[0])) {
246: do_system();
247: if (interactive) /* 3.5 did it unconditionally */
248: (void) fputs("!\n", stderr); /* why do we need this ? */
249: return (0);
250: }
251: num_tokens = scanner(input_line);
252: c_token = 0;
253: while (c_token < num_tokens) {
254: if (command())
255: return (1);
256: if (c_token < num_tokens) { /* something after command */
257: if (equals(c_token, ";"))
258: c_token++;
259: else
260: int_error("';' expected", c_token);
261: }
262: }
263: return (0);
264: }
265:
266:
267: void define()
268: {
269: register int start_token; /* the 1st token in the function definition */
270: register struct udvt_entry *udv;
271: register struct udft_entry *udf;
272:
273: if (equals(c_token + 1, "(")) {
274: /* function ! */
275: int dummy_num = 0;
276: struct at_type *at_tmp;
277: char save_dummy[MAX_NUM_VAR][MAX_ID_LEN + 1];
278: memcpy(save_dummy, c_dummy_var, sizeof(save_dummy));
279: start_token = c_token;
280: do {
281: c_token += 2; /* skip to the next dummy */
282: copy_str(c_dummy_var[dummy_num++], c_token, MAX_ID_LEN);
283: } while (equals(c_token + 1, ",") && (dummy_num < MAX_NUM_VAR));
284: if (equals(c_token + 1, ","))
285: int_error("function contains too many parameters", c_token + 2);
286: c_token += 3; /* skip (, dummy, ) and = */
287: if (END_OF_COMMAND)
288: int_error("function definition expected", c_token);
289: udf = dummy_func = add_udf(start_token);
290: if ((at_tmp = perm_at()) == (struct at_type *) NULL)
291: int_error("not enough memory for function", start_token);
292: if (udf->at) /* already a dynamic a.t. there */
293: free((char *) udf->at); /* so free it first */
294: udf->at = at_tmp; /* before re-assigning it. */
295: memcpy(c_dummy_var, save_dummy, sizeof(save_dummy));
296: m_capture(&(udf->definition), start_token, c_token - 1);
297: dummy_func = NULL; /* dont let anyone else use our workspace */
298: } else {
299: /* variable ! */
300: start_token = c_token;
301: c_token += 2;
302: udv = add_udv(start_token);
303: (void) const_express(&(udv->udv_value));
304: udv->udv_undef = FALSE;
305: }
306: }
307:
308:
309: static int command()
310: {
311: FILE *fp;
312: int i;
313: /* string holding name of save or load file */
314: char sv_file[MAX_LINE_LEN + 1];
315:
316: for (i = 0; i < MAX_NUM_VAR; i++)
317: c_dummy_var[i][0] = NUL; /* no dummy variables */
318:
319: if (is_definition(c_token))
320: define();
321: else if (almost_equals(c_token, "h$elp") || equals(c_token, "?")) {
322: c_token++;
323: do_help(1);
324: } else if (equals(c_token, "testtime")) {
325: /* given a format and a time string, exercise the time code */
326: char format[160], string[160];
327: struct tm tm;
328: double secs;
329: if (isstring(++c_token)) {
330: quote_str(format, c_token, 159);
331: if (isstring(++c_token)) {
332: quote_str(string, c_token++, 159);
333: memset(&tm, 0, sizeof(tm));
334: gstrptime(string, format, &tm);
335: secs = gtimegm(&tm);
336: fprintf(stderr, "internal = %f - %d/%d/%d::%d:%d:%d , wday=%d, yday=%d\n",
337: secs, tm.tm_mday, tm.tm_mon + 1, tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday, tm.tm_yday);
338: memset(&tm, 0, sizeof(tm));
339: ggmtime(&tm, secs);
340: gstrftime(string, 159, format, secs);
341: fprintf(stderr, "convert back \"%s\" - %d/%d/%d::%d:%d:%d , wday=%d, yday=%d\n",
342: string, tm.tm_mday, tm.tm_mon + 1, tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday, tm.tm_yday);
343: }
344: }
345: } else if (almost_equals(c_token, "test")) {
346: c_token++;
347: test_term();
348: } else if (almost_equals(c_token, "scr$eendump")) {
349: c_token++;
350: #ifdef _Windows
351: screen_dump();
352: #else
353: fputs("screendump not implemented\n", stderr);
354: #endif
355: } else if (almost_equals(c_token, "pa$use")) {
356: struct value a;
357: int sleep_time, text = 0;
358: char buf[MAX_LINE_LEN + 1];
359:
360: c_token++;
361: sleep_time = (int) real(const_express(&a));
362: buf[0] = NUL;
363: if (!(END_OF_COMMAND)) {
364: if (!isstring(c_token))
365: int_error("expecting string", c_token);
366: else {
367: quote_str(buf, c_token, MAX_LINE_LEN);
368: ++c_token;
369: #ifdef _Windows
370: if (sleep_time >= 0)
371: #else
372: # ifdef OS2
373: if (strcmp(term->name, "pm") != 0 || sleep_time >= 0)
374: # else
375: # ifdef MTOS
376: if (strcmp(term->name, "mtos") != 0 || sleep_time >= 0)
377: # endif /* MTOS */
378: # endif /* OS2 */
379: #endif /* _Windows */
380: fputs(buf, stderr);
381: text = 1;
382: }
383: }
384: if (sleep_time < 0) {
385: #ifdef _Windows
386: if (!Pause(buf))
387: bail_to_command_line();
388: #else
389: # ifdef OS2
390: if (strcmp(term->name, "pm") == 0 && sleep_time < 0) {
391: int rc;
392: if ((rc = PM_pause(buf)) == 0)
393: bail_to_command_line();
394: else if (rc == 2) {
395: fputs(buf, stderr);
396: text = 1;
397: (void) fgets(buf, MAX_LINE_LEN, stdin);
398: }
399: }
400: # else /* !OS2 */
401: # ifdef _Macintosh
402: if (strcmp(term->name, "macintosh") == 0 && sleep_time < 0)
403: Pause(sleep_time);
404: # else /* !_Macintosh */
405: # ifdef MTOS
406: if (strcmp(term->name, "mtos") == 0) {
407: int MTOS_pause(char *buf);
408: int rc;
409: if ((rc = MTOS_pause(buf)) == 0)
410: bail_to_command_line();
411: else if (rc == 2) {
412: fputs(buf, stderr);
413: text = 1;
414: (void) fgets(buf, MAX_LINE_LEN, stdin);
415: }
416: } else if (strcmp(term->name, "atari") == 0) {
417: char *readline(char *);
418: char *line = readline("");
419: if (line)
420: free(line);
421: } else
422: (void) fgets(buf, MAX_LINE_LEN, stdin);
423: # else /* !MTOS */
424: # ifdef ATARI
425: if (strcmp(term->name, "atari") == 0) {
426: char *readline(char *);
427: char *line = readline("");
428: if (line)
429: free(line);
430: } else
431: (void) fgets(buf, MAX_LINE_LEN, stdin);
432: # else /* !ATARI */
433: (void) fgets(buf, MAX_LINE_LEN, stdin);
434: /* Hold until CR hit. */
435: # endif /* !ATARI */
436: # endif /* !MTOS */
437: # endif /* !_Macintosh */
438: # endif /* !OS2 */
439: #endif
440: }
441: if (sleep_time > 0)
442: GP_SLEEP(sleep_time);
443:
444: if (text != 0 && sleep_time >= 0)
445: fputc('\n', stderr);
446: screen_ok = FALSE;
447: } else if (almost_equals(c_token, "pr$int")) {
448: int need_space = 0; /* space printed between two expressions only */
449: screen_ok = FALSE;
450: do {
451: ++c_token;
452: if (isstring(c_token)) {
453: char s[MAX_LINE_LEN];
454: quote_str(s, c_token, MAX_LINE_LEN);
455: fputs(s, stderr);
456: need_space = 0;
457: ++c_token;
458: } else {
459: struct value a;
460: (void) const_express(&a);
461: if (need_space)
462: putc(' ', stderr);
463: need_space = 1;
464: disp_value(stderr, &a);
465: }
466: } while (!END_OF_COMMAND && equals(c_token, ","));
467:
468: (void) putc('\n', stderr);
469: } else if (almost_equals(c_token, "fit")) {
470: ++c_token;
471: do_fit();
472: } else if (almost_equals(c_token, "up$date")) {
473: char tmps[80];
474: char tmps2[80];
475: /* Have to initialise tmps2, otherwise
476: * update() cannot decide whether a valid
477: * filename was given. lh
478: */
479: tmps2[0] = NUL;
480: if (!isstring(++c_token))
481: int_error("Parameter filename expected", c_token);
482: quote_str(tmps, c_token++, 80);
483: if (!(END_OF_COMMAND)) {
484: if (!isstring(c_token))
485: int_error("New parameter filename expected", c_token);
486: else
487: quote_str(tmps2, c_token++, 80);
488: }
489: update(tmps, tmps2);
490: } else if (almost_equals(c_token, "p$lot")) {
491: plot_token = c_token++;
492: SET_CURSOR_WAIT;
493: plotrequest();
494: SET_CURSOR_ARROW;
495: } else if (almost_equals(c_token, "sp$lot")) {
496: plot_token = c_token++;
497: SET_CURSOR_WAIT;
498: plot3drequest();
499: SET_CURSOR_ARROW;
500: } else if (almost_equals(c_token, "rep$lot")) {
501: if (replot_line[0] == NUL)
502: int_error("no previous plot", c_token);
503: c_token++;
504: SET_CURSOR_WAIT;
505: replotrequest();
506: SET_CURSOR_ARROW;
507: } else if (almost_equals(c_token, "se$t"))
508: set_command();
509: else if (almost_equals(c_token, "res$et"))
510: reset_command();
511: else if (almost_equals(c_token, "sh$ow"))
512: show_command();
513: else if (almost_equals(c_token, "cl$ear")) {
514: term_start_plot();
515:
516: if (multiplot && term->fillbox) {
517: unsigned int x1 = (unsigned int) (xoffset * term->xmax);
518: unsigned int y1 = (unsigned int) (yoffset * term->ymax);
519: unsigned int width = (unsigned int) (xsize * term->xmax);
520: unsigned int height = (unsigned int) (ysize * term->ymax);
521: (*term->fillbox) (0, x1, y1, width, height);
522: }
523: term_end_plot();
524:
525: screen_ok = FALSE;
526: c_token++;
527: } else if (almost_equals(c_token, "she$ll")) {
528: do_shell();
529: screen_ok = FALSE;
530: c_token++;
531: } else if (almost_equals(c_token, "sa$ve")) {
532: if (almost_equals(++c_token, "f$unctions")) {
533: if (!isstring(++c_token))
534: int_error("expecting filename", c_token);
535: else {
536: quote_str(sv_file, c_token, MAX_LINE_LEN);
537: save_functions(fopen(sv_file, "w"));
538: }
539: } else if (almost_equals(c_token, "v$ariables")) {
540: if (!isstring(++c_token))
541: int_error("expecting filename", c_token);
542: else {
543: quote_str(sv_file, c_token, MAX_LINE_LEN);
544: save_variables(fopen(sv_file, "w"));
545: }
546: } else if (almost_equals(c_token, "s$et")) {
547: if (!isstring(++c_token))
548: int_error("expecting filename", c_token);
549: else {
550: quote_str(sv_file, c_token, MAX_LINE_LEN);
551: save_set(fopen(sv_file, "w"));
552: }
553: } else if (isstring(c_token)) {
554: quote_str(sv_file, c_token, MAX_LINE_LEN);
555: save_all(fopen(sv_file, "w"));
556: } else {
557: int_error("filename or keyword 'functions', 'variables', or 'set' expected", c_token);
558: }
559: c_token++;
560: } else if (almost_equals(c_token, "l$oad")) {
561: if (!isstring(++c_token))
562: int_error("expecting filename", c_token);
563: else {
564: quote_str(sv_file, c_token, MAX_LINE_LEN);
565: /* load_file(fp=fopen(sv_file, "r"), sv_file, FALSE); OLD
566: * DBT 10/6/98 handle stdin as special case
567: * passes it on to load_file() so that it gets
568: * pushed on the stack and recusion will work, etc
569: */
570: fp = strcmp(sv_file, "-") ? fopen(sv_file, "r") : stdin;
571: load_file(fp, sv_file, FALSE);
572: /* input_line[] and token[] now destroyed! */
573: c_token = num_tokens = 0;
574: }
575: } else if (almost_equals(c_token, "ca$ll")) {
576: if (!isstring(++c_token))
577: int_error("expecting filename", c_token);
578: else {
579: quote_str(sv_file, c_token, MAX_LINE_LEN);
580: load_file(fopen(sv_file, "r"), sv_file, TRUE); /* Argument list follows filename */
581: /* input_line[] and token[] now destroyed! */
582: c_token = num_tokens = 0;
583: }
584: } else if (almost_equals(c_token, "if")) {
585: double exprval;
586: struct value t;
587: if (!equals(++c_token, "(")) /* no expression */
588: int_error("expecting (expression)", c_token);
589: exprval = real(const_express(&t));
590: if (exprval != 0.0) {
591: /* fake the condition of a ';' between commands */
592: int eolpos = token[num_tokens - 1].start_index + token[num_tokens - 1].length;
593: --c_token;
594: token[c_token].length = 1;
595: token[c_token].start_index = eolpos + 2;
596: input_line[eolpos + 2] = ';';
597: input_line[eolpos + 3] = NUL;
598: } else
599: c_token = num_tokens = 0;
600: } else if (almost_equals(c_token, "rer$ead")) {
601: fp = lf_top();
602: if (fp != (FILE *) NULL)
603: rewind(fp);
604: c_token++;
605: } else if (almost_equals(c_token, "cd")) {
606: if (!isstring(++c_token))
607: int_error("expecting directory name", c_token);
608: else {
609: quote_str(sv_file, c_token, MAX_LINE_LEN);
610: if (changedir(sv_file)) {
611: int_error("Can't change to this directory", c_token);
612: }
613: c_token++;
614: }
615: } else if (almost_equals(c_token, "pwd")) {
616: GP_GETCWD(sv_file, sizeof(sv_file));
617: fprintf(stderr, "%s\n", sv_file);
618: c_token++;
619: } else if (almost_equals(c_token, "ex$it") ||
620: almost_equals(c_token, "q$uit")) {
621: /* graphics will be tidied up in main */
622: return (1);
623: } else if (!equals(c_token, ";")) { /* null statement */
624: #ifdef OS2
625: if (_osmode == OS2_MODE) {
626: if (token[c_token].is_token) {
627: int rc;
628: rc = ExecuteMacro(input_line + token[c_token].start_index,
629: token[c_token].length);
630: if (rc == 0) {
631: c_token = num_tokens = 0;
632: return (0);
633: }
634: }
635: }
636: #endif
637: int_error("invalid command", c_token);
638: }
639: return (0);
640: }
641:
642:
643: void done(status)
644: int status;
645: {
646: term_reset();
647: exit(status);
648: }
649:
650: static int changedir(path)
651: char *path;
652: {
653: #if defined(MSDOS) || defined(WIN16) || defined(ATARI) || defined(DOS386)
654: # if defined(__ZTC__)
655: unsigned dummy; /* it's a parameter needed for dos_setdrive */
656: # endif
657:
658: /* first deal with drive letter */
659:
660: if (isalpha(path[0]) && (path[1] == ':')) {
661: int driveno = toupper(path[0]) - 'A'; /* 0=A, 1=B, ... */
662:
663: # if defined(ATARI)
664: (void) Dsetdrv(driveno);
665: # endif
666:
667: # if defined(__ZTC__)
668: (void) dos_setdrive(driveno + 1, &dummy);
669: # endif
670:
671: # if (defined(MSDOS) && defined(__EMX__)) || defined(__MSC__)
672: (void) _chdrive(driveno + 1);
673: # endif
674:
675:
676: /* HBB: recent versions of DJGPP also have setdisk():,
677: * so I del'ed the special code */
678: # if ((defined(MSDOS) || defined(_Windows)) && defined(__TURBOC__)) || defined(DJGPP)
679: (void) setdisk(driveno);
680: # endif
681: path += 2; /* move past drive letter */
682: }
683: /* then change to actual directory */
684: if (*path)
685: if (chdir(path))
686: return 1;
687:
688: return 0; /* should report error with setdrive also */
689:
690: #elif defined(WIN32)
691: return !(SetCurrentDirectory(path));
692: #else
693: return chdir(path);
694: #endif /* MSDOS, ATARI etc. */
695: }
696:
697:
698: void replotrequest()
699: {
700: if (equals(c_token, "["))
701: int_error("cannot set range with replot", c_token);
702:
703: /* do not store directly into the replot_line string, until the
704: * new plot line has been successfully plotted. This way,
705: * if user makes a typo in a replot line, they do not have
706: * to start from scratch. The replot_line will be committed
707: * after do_plot has returned, whence we know all is well
708: */
709: if (END_OF_COMMAND) {
710: /* it must already be long enough, but lets make sure */
711: int len = strlen(replot_line) + 1;
712: while (input_line_len < len)
713: extend_input_line();
714: strcpy(input_line, replot_line);
715: } else {
716: char *replot_args = NULL; /* else m_capture will free it */
717: int last_token = num_tokens - 1;
718: /* length = length of old part + length of new part + ',' + \0 */
719: int newlen = strlen(replot_line) + token[last_token].start_index + token[last_token].length - token[c_token].start_index + 2;
720: m_capture(&replot_args, c_token, last_token); /* might be empty */
721: while (input_line_len < newlen)
722: extend_input_line();
723: strcpy(input_line, replot_line);
724: strcat(input_line, ",");
725: strcat(input_line, replot_args);
726: free(replot_args);
727: }
728: plot_token = 0; /* whole line to be saved as replot line */
729:
730: screen_ok = FALSE;
731: num_tokens = scanner(input_line);
732: c_token = 1; /* skip the 'plot' part */
733: if (is_3d_plot)
734: plot3drequest();
735: else
736: plotrequest();
737: }
738:
739:
740: /* Support for input, shell, and help for various systems */
741:
742: #ifdef VMS
743:
744: # include <descrip.h>
745: # include <rmsdef.h>
746: # include <smgdef.h>
747: # include <smgmsg.h>
748:
749: extern lib$get_input(), lib$put_output();
750: extern smg$read_composed_line();
751: extern sys$putmsg();
752: extern lbr$output_help();
753: extern lib$spawn();
754:
755: int vms_len;
756:
757: unsigned int status[2] = {1, 0};
758:
759: static char Help[MAX_LINE_LEN+1] = "gnuplot";
760:
761: $DESCRIPTOR(prompt_desc, PROMPT);
762: /* temporary fix until change to variable length */
763: struct dsc$descriptor_s line_desc =
764: {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
765:
766: $DESCRIPTOR(help_desc, Help);
767: $DESCRIPTOR(helpfile_desc, "GNUPLOT$HELP");
768:
769: /* please note that the vms version of read_line doesn't support variable line
770: length (yet) */
771:
772: static int read_line(prompt)
773: char *prompt;
774: {
775: int more, start = 0;
776: char expand_prompt[40];
777:
778: prompt_desc.dsc$w_length = strlen(prompt);
779: prompt_desc.dsc$a_pointer = prompt;
780: (void) strcpy(expand_prompt, "_");
781: (void) strncat(expand_prompt, prompt, 38);
782: do {
783: line_desc.dsc$w_length = MAX_LINE_LEN - start;
784: line_desc.dsc$a_pointer = &input_line[start];
785: switch (status[1] = smg$read_composed_line(&vms_vkid, &vms_ktid, &line_desc, &prompt_desc, &vms_len)) {
786: case SMG$_EOF:
787: done(IO_SUCCESS); /* ^Z isn't really an error */
788: break;
789: case RMS$_TNS: /* didn't press return in time */
790: vms_len--; /* skip the last character */
791: break; /* and parse anyway */
792: case RMS$_BES: /* Bad Escape Sequence */
793: case RMS$_PES: /* Partial Escape Sequence */
794: sys$putmsg(status);
795: vms_len = 0; /* ignore the line */
796: break;
797: case SS$_NORMAL:
798: break; /* everything's fine */
799: default:
800: done(status[1]); /* give the error message */
801: }
802: start += vms_len;
803: input_line[start] = NUL;
804: inline_num++;
805: if (input_line[start - 1] == '\\') {
806: /* Allow for a continuation line. */
807: prompt_desc.dsc$w_length = strlen(expand_prompt);
808: prompt_desc.dsc$a_pointer = expand_prompt;
809: more = 1;
810: --start;
811: } else {
812: line_desc.dsc$w_length = strlen(input_line);
813: line_desc.dsc$a_pointer = input_line;
814: more = 0;
815: }
816: } while (more);
817: return 0;
818: }
819:
820:
821: # ifdef NO_GIH
822: static void do_help(toplevel)
823: int toplevel; /* not used for VMS version */
824: {
825: int first = c_token;
826: while (!END_OF_COMMAND)
827: ++c_token;
828:
829: strcpy(Help, "GNUPLOT ");
830: capture(Help + 8, first, c_token - 1, sizeof(Help) - 9);
831: help_desc.dsc$w_length = strlen(Help);
832: if ((vaxc$errno = lbr$output_help(lib$put_output, 0, &help_desc,
833: &helpfile_desc, 0, lib$get_input)) != SS$_NORMAL)
834: os_error("can't open GNUPLOT$HELP", NO_CARET);
835: }
836:
837: # endif /* NO_GIH */
838:
839: static void do_shell()
840: {
841: if ((vaxc$errno = lib$spawn()) != SS$_NORMAL) {
842: os_error("spawn error", NO_CARET);
843: }
844: }
845:
846:
847: static void do_system()
848: {
849: /* input_line[0] = ' '; an embarrassment, but... */
850:
851: /* input_line is filled by read_line or load_file, but
852: * line_desc length is set only by read_line; adjust now
853: */
854: line_desc.dsc$w_length = strlen(input_line) - 1;
855: line_desc.dsc$a_pointer = &input_line[1];
856:
857: if ((vaxc$errno = lib$spawn(&line_desc)) != SS$_NORMAL)
858: os_error("spawn error", NO_CARET);
859:
860: (void) putc('\n', stderr);
861: }
862:
863: #endif /* VMS */
864:
865:
866: #ifdef _Windows
867:
868: # ifdef NO_GIH
869: static void do_help(toplevel)
870: int toplevel; /* not used for windows */
871: {
872: if (END_OF_COMMAND)
873: WinHelp(textwin.hWndParent, (LPSTR) winhelpname, HELP_INDEX, (DWORD) NULL);
874: else {
875: char buf[128];
876: int start = c_token++;
877: while (!(END_OF_COMMAND))
878: c_token++;
879: capture(buf, start, c_token - 1, 128);
880: WinHelp(textwin.hWndParent, (LPSTR) winhelpname, HELP_PARTIALKEY, (DWORD) buf);
881: }
882: }
883: # endif /* NO_GIH */
884: #endif /* _Windows */
885:
886: /*
887: * do_help: (not VMS, although it would work) Give help to the user. It
888: * parses the command line into helpbuf and supplies help for that string.
889: * Then, if there are subtopics available for that key, it prompts the user
890: * with this string. If more input is given, do_help is called recursively,
891: * with argument 0. Thus a more specific help can be supplied. This can be
892: * done repeatedly. If null input is given, the function returns, effecting
893: * a backward climb up the tree.
894: * David Kotz (David.Kotz@Dartmouth.edu) 10/89
895: * drd - The help buffer is first cleared when called with toplevel=1.
896: * This is to fix a bug where help is broken if ^C is pressed whilst in the
897: * help.
898: */
899:
900: #ifndef NO_GIH
901: static void do_help(toplevel)
902: int toplevel;
903: {
904: static char *helpbuf = NULL;
905: static char *prompt = NULL;
906: int base; /* index of first char AFTER help string */
907: int len; /* length of current help string */
908: TBOOLEAN more_help;
909: TBOOLEAN only; /* TRUE if only printing subtopics */
910: int subtopics; /* 0 if no subtopics for this topic */
911: int start; /* starting token of help string */
912: char *help_ptr; /* name of help file */
913: # if defined(SHELFIND)
914: static char help_fname[256] = ""; /* keep helpfilename across calls */
915: # endif
916:
917: # if defined(MTOS) || defined(ATARI)
918: char const *const ext[] = {NULL};
919: # endif
920:
921: if ((help_ptr = getenv("GNUHELP")) == (char *) NULL)
922: # ifndef SHELFIND
923: /* if can't find environment variable then just use HELPFILE */
924:
925: /* patch by David J. Liu for getting GNUHELP from home directory */
926: # if (defined(__TURBOC__) && (defined(MSDOS) || defined(DOS386))) || defined(__DJGPP__)
927: help_ptr = HelpFile;
928: # else
929: # if defined(MTOS) || defined(ATARI)
930: {
931: if ((help_ptr = findfile(HELPFILE, getenv("GNUPLOTPATH"), ext)) == NULL)
932: help_ptr = findfile(HELPFILE, getenv("PATH"), ext);
933: if (!help_ptr)
934: help_ptr = HELPFILE;
935: }
936: # else
937: help_ptr = HELPFILE;
938: # endif /* MTOS || ATARI */
939: # endif /* __TURBOC__ */
940: /* end of patch - DJL */
941:
942: # else /* !SHELFIND */
943: /* try whether we can find the helpfile via shell_find. If not, just
944: use the default. (tnx Andreas) */
945:
946: if (!strchr(HELPFILE, ':') && !strchr(HELPFILE, '/') &&
947: !strchr(HELPFILE, '\\')) {
948: if (strlen(help_fname) == 0) {
949: strcpy(help_fname, HELPFILE);
950: if (shel_find(help_fname) == 0) {
951: strcpy(help_fname, HELPFILE);
952: }
953: }
954: help_ptr = help_fname;
955: } else {
956: help_ptr = HELPFILE;
957: }
958: # endif /* !SHELFIND */
959:
960: /* Since MSDOS DGROUP segment is being overflowed we can not allow such */
961: /* huge static variables (1k each). Instead we dynamically allocate them */
962: /* on the first call to this function... */
963: if (helpbuf == NULL) {
964: helpbuf = gp_alloc((unsigned long) MAX_LINE_LEN, "help buffer");
965: prompt = gp_alloc((unsigned long) MAX_LINE_LEN, "help prompt");
966: helpbuf[0] = prompt[0] = 0;
967: }
968: if (toplevel)
969: helpbuf[0] = prompt[0] = 0; /* in case user hit ^c last time */
970:
971: len = base = strlen(helpbuf);
972:
973: /* find the end of the help command */
974: for (start = c_token; !(END_OF_COMMAND); c_token++);
975: /* copy new help input into helpbuf */
976: if (len > 0)
977: helpbuf[len++] = ' '; /* add a space */
978: capture(helpbuf + len, start, c_token - 1, MAX_LINE_LEN - len);
979: squash_spaces(helpbuf + base); /* only bother with new stuff */
980: lower_case(helpbuf + base); /* only bother with new stuff */
981: len = strlen(helpbuf);
982:
983: /* now, a lone ? will print subtopics only */
984: if (strcmp(helpbuf + (base ? base + 1 : 0), "?") == 0) {
985: /* subtopics only */
986: subtopics = 1;
987: only = TRUE;
988: helpbuf[base] = NUL; /* cut off question mark */
989: } else {
990: /* normal help request */
991: subtopics = 0;
992: only = FALSE;
993: }
994:
995: switch (help(helpbuf, help_ptr, &subtopics)) {
996: case H_FOUND:{
997: /* already printed the help info */
998: /* subtopics now is true if there were any subtopics */
999: screen_ok = FALSE;
1000:
1001: do {
1002: if (subtopics && !only) {
1003: /* prompt for subtopic with current help string */
1004: if (len > 0)
1005: (void) sprintf(prompt, "Subtopic of %s: ", helpbuf);
1006: else
1007: (void) strcpy(prompt, "Help topic: ");
1008: read_line(prompt);
1009: num_tokens = scanner(input_line);
1010: c_token = 0;
1011: more_help = !(END_OF_COMMAND);
1012: if (more_help)
1013: /* base for next level is all of current helpbuf */
1014: do_help(0);
1015: } else
1016: more_help = FALSE;
1017: } while (more_help);
1018:
1019: break;
1020: }
1021: case H_NOTFOUND:{
1022: printf("Sorry, no help for '%s'\n", helpbuf);
1023: break;
1024: }
1025: case H_ERROR:{
1026: perror(help_ptr);
1027: break;
1028: }
1029: default:{ /* defensive programming */
1030: int_error("Impossible case in switch", NO_CARET);
1031: /* NOTREACHED */
1032: }
1033: }
1034:
1035: helpbuf[base] = NUL; /* cut it off where we started */
1036: }
1037: #endif /* !NO_GIH */
1038:
1039:
1040: #ifndef VMS
1041:
1042: # ifdef AMIGA_AC_5
1043: static char *parms[80];
1044: static char strg0[256];
1045: static void getparms __PROTO((char *, char**));
1046: # endif
1047:
1048: static void do_system()
1049: {
1050: # ifdef AMIGA_AC_5
1051: getparms(input_line + 1, parms);
1052: fexecv(parms[0], parms);
1053: # elif (defined(ATARI) && defined(__GNUC__))
1054: /* || (defined(MTOS) && defined(__GNUC__)) */
1055: /* use preloaded shell, if available */
1056: short (*shell_p) (char *command);
1057: void *ssp;
1058:
1059: ssp = (void *) Super(NULL);
1060: shell_p = *(short (**)(char *)) 0x4f6;
1061: Super(ssp);
1062:
1063: /* this is a bit strange, but we have to have a single if */
1064: if (shell_p)
1065: (*shell_p) (input_line + 1);
1066: else
1067: system(input_line + 1);
1068: # elif defined(_Windows)
1069: winsystem(input_line + 1);
1070: # else /* !(AMIGA_AC_5 || ATARI && __GNUC__ || _Windows) */
1071: /* (am, 19980929)
1072: * OS/2 related note: cmd.exe returns 255 if called w/o argument.
1073: * i.e. calling a shell by "!" will always end with an error message.
1074: * A workaround has to include checking for EMX,OS/2, two environment
1075: * variables,...
1076: */
1077: system(input_line + 1);
1078: # endif /* !(AMIGA_AC_5 || ATARI&&__GNUC__ || _Windows) */
1079: }
1080:
1081:
1082: # ifdef AMIGA_AC_5
1083: /******************************************************************************
1084: * Parses the command string (for fexecv use) and converts the first token
1085: * to lower case
1086: *****************************************************************************/
1087: static void getparms(command, parms)
1088: char *command;
1089: char **parms;
1090: {
1091: register int i = 0; /* A bunch of indices */
1092: register int j = 0;
1093: register int k = 0;
1094:
1095: while (*(command + j) != NUL) { /* Loop on string characters */
1096: parms[k++] = strg0 + i;
1097: while (*(command + j) == ' ')
1098: ++j;
1099: while (*(command + j) != ' ' && *(command + j) != NUL) {
1100: if (*(command + j) == '"') /* Get quoted string */
1101: for (*(strg0 + (i++)) = *(command + (j++));
1102: *(command + j) != '"';
1103: *(strg0 + (i++)) = *(command + (j++)));
1104: *(strg0 + (i++)) = *(command + (j++));
1105: }
1106: *(strg0 + (i++)) = NUL; /* NUL terminate every token */
1107: }
1108: parms[k] = NUL;
1109:
1110: for (k = strlen(strg0) - 1; k >= 0; --k) /* Convert to lower case */
1111: *(strg0 + k) >= 'A' && *(strg0 + k) <= 'Z' ? *(strg0 + k) |= 32 : *(strg0 + k);
1112: }
1113:
1114: # endif /* AMIGA_AC_5 */
1115:
1116:
1117: # if defined(READLINE) || defined(GNU_READLINE)
1118: /* keep some compilers happy */
1119: static char *rlgets __PROTO((char *s, int n, char *prompt));
1120:
1121: static char * rlgets(s, n, prompt)
1122: char *s;
1123: int n;
1124: char *prompt;
1125: {
1126: static char *line = (char *) NULL;
1127: static int leftover = -1; /* index of 1st char leftover from last call */
1128:
1129: if (leftover == -1) {
1130: /* If we already have a line, first free it */
1131: if (line != (char *) NULL) {
1132: free(line);
1133: line = NULL;
1134: /* so that ^C or int_error during readline() does
1135: * not result in line being free-ed twice */
1136: }
1137: line = readline((interactive) ? prompt : "");
1138: leftover = 0;
1139: /* If it's not an EOF */
1140: if (line && *line)
1141: add_history(line);
1142: }
1143: if (line) {
1144: safe_strncpy(s, line + leftover, n);
1145: leftover += strlen(s);
1146: if (line[leftover] == NUL)
1147: leftover = -1;
1148: return s;
1149: }
1150: return NULL;
1151: }
1152: # endif /* READLINE || GNU_READLINE */
1153:
1154:
1155: # if defined(MSDOS) || defined(_Windows) || defined(DOS386)
1156: static void do_shell()
1157: {
1158: register char *comspec;
1159: if ((comspec = getenv("COMSPEC")) == (char *) NULL)
1160: comspec = "\\command.com";
1161: # ifdef _Windows
1162: if (WinExec(comspec, SW_SHOWNORMAL) <= 32)
1163: # else
1164: # ifdef DJGPP
1165: if (system(comspec) == -1)
1166: # else
1167: if (spawnl(P_WAIT, comspec, NULL) == -1)
1168: # endif /* !DJGPP */
1169: # endif /* !_Windows */
1170: os_error("unable to spawn shell", NO_CARET);
1171: }
1172:
1173: # else /* !MSDOS */
1174:
1175: /* plain old Unix */
1176:
1177: # ifdef AMIGA_SC_6_1
1178: static void do_shell()
1179: {
1180: register char *shell;
1181: if (!(shell = getenv("SHELL")))
1182: shell = SHELL;
1183:
1184: if (system(shell))
1185: os_error("system() failed", NO_CARET);
1186:
1187: (void) putc('\n', stderr);
1188: }
1189:
1190: # else /* !AMIGA_SC_6_1 */
1191:
1192: # ifdef OS2
1193: static void do_shell()
1194: {
1195: register char *shell;
1196: if (!(shell = getenv("SHELL")) && !(shell = getenv("COMSPEC")))
1197: shell = SHELL;
1198:
1199: if (system(shell) == -1)
1200: os_error("system() failed", NO_CARET);
1201:
1202: (void) putc('\n', stderr);
1203: }
1204: # else /* !OS2 */
1205:
1206: #define EXEC "exec "
1207: static void do_shell()
1208: {
1209: static char exec[100] = EXEC;
1210: register char *shell;
1211: if (!(shell = getenv("SHELL")))
1212: shell = SHELL;
1213:
1214: if (system(safe_strncpy(&exec[sizeof(EXEC) - 1], shell,
1215: sizeof(exec) - sizeof(EXEC) - 1)))
1216: os_error("system() failed", NO_CARET);
1217:
1218: (void) putc('\n', stderr);
1219: }
1220:
1221: # endif /* !OS2 */
1222: # endif /* !AMIGA_SC_6_1 */
1223: # endif /* !MSDOS */
1224:
1225: /* read from stdin, everything except VMS */
1226:
1227: # if !defined(READLINE) && !defined(GNU_READLINE)
1228: # if (defined(MSDOS) || defined(DOS386)) && !defined(_Windows) && !defined(__EMX__) && !defined(DJGPP)
1229:
1230: /* if interactive use console IO so CED will work */
1231:
1232: #define PUT_STRING(s) cputs(s)
1233: #define GET_STRING(s,l) ((interactive) ? cgets_emu(s,l) : fgets(s,l,stdin))
1234:
1235: # ifdef __TURBOC__
1236: /* cgets implemented using dos functions */
1237: /* Maurice Castro 22/5/91 */
1238: static char *doscgets __PROTO((char *));
1239:
1240: static char *doscgets(s)
1241: char *s;
1242: {
1243: long datseg;
1244:
1245: /* protect and preserve segments - call dos to do the dirty work */
1246: datseg = _DS;
1247:
1248: _DX = FP_OFF(s);
1249: _DS = FP_SEG(s);
1250: _AH = 0x0A;
1251: geninterrupt(33);
1252: _DS = datseg;
1253:
1254: /* check for a carriage return and then clobber it with a null */
1255: if (s[s[1] + 2] == '\r')
1256: s[s[1] + 2] = 0;
1257:
1258: /* return the input string */
1259: return (&(s[2]));
1260: }
1261: # endif /* __TURBOC__ */
1262:
1263: # ifdef __ZTC__
1264: void cputs(char *s)
1265: {
1266: register int i = 0;
1267: while (s[i] != NUL)
1268: bdos(0x02, s[i++], NULL);
1269: }
1270:
1271: char *cgets(char *s)
1272: {
1273: bdosx(0x0A, s, NULL);
1274:
1275: if (s[s[1] + 2] == '\r')
1276: s[s[1] + 2] = 0;
1277:
1278: /* return the input string */
1279: return (&(s[2]));
1280: }
1281: # endif /* __ZTC__ */
1282:
1283: /* emulate a fgets like input function with DOS cgets */
1284: char *cgets_emu(str, len)
1285: char *str;
1286: int len;
1287: {
1288: static char buffer[128] = "";
1289: static int leftover = 0;
1290:
1291: if (buffer[leftover] == NUL) {
1292: buffer[0] = 126;
1293: # ifdef __TURBOC__
1294: doscgets(buffer);
1295: # else
1296: cgets(buffer);
1297: # endif
1298: fputc('\n', stderr);
1299: if (buffer[2] == 26)
1300: return NULL;
1301: leftover = 2;
1302: }
1303: safe_strncpy(str, buffer + leftover, len);
1304: leftover += strlen(str);
1305: return str;
1306: }
1307: # else /* !plain DOS */
1308:
1309: # define PUT_STRING(s) fputs(s, stderr)
1310: # define GET_STRING(s,l) fgets(s, l, stdin)
1311:
1312: # endif /* !plain DOS */
1313: # endif /* !READLINE && !GNU_READLINE) */
1314:
1315: /* Non-VMS version */
1316: static int read_line(prompt)
1317: char *prompt;
1318: {
1319: int start = 0;
1320: TBOOLEAN more = FALSE;
1321: int last = 0;
1322:
1323: # if !defined(READLINE) && !defined(GNU_READLINE)
1324: if (interactive)
1325: PUT_STRING(prompt);
1326: # endif /* READLINE */
1327: do {
1328: /* grab some input */
1329: # if defined(READLINE) || defined(GNU_READLINE)
1330: if (((interactive)
1331: ? rlgets(&(input_line[start]), input_line_len - start,
1332: ((more) ? "> " : prompt))
1333: : fgets(&(input_line[start]), input_line_len - start, stdin))
1334: == (char *) NULL) {
1335: # else /* !(READLINE || GNU_READLINE) */
1336: if (GET_STRING(&(input_line[start]), input_line_len - start)
1337: == (char *) NULL) {
1338: # endif /* !(READLINE || GNU_READLINE) */
1339: /* end-of-file */
1340: if (interactive)
1341: (void) putc('\n', stderr);
1342: input_line[start] = NUL;
1343: inline_num++;
1344: if (start > 0) /* don't quit yet - process what we have */
1345: more = FALSE;
1346: else
1347: return (1); /* exit gnuplot */
1348: } else {
1349: /* normal line input */
1350: last = strlen(input_line) - 1;
1351: if (last >= 0) {
1352: if (input_line[last] == '\n') { /* remove any newline */
1353: input_line[last] = NUL;
1354: /* Watch out that we don't backup beyond 0 (1-1-1) */
1355: if (last > 0)
1356: --last;
1357: } else if (last + 2 >= input_line_len) {
1358: extend_input_line();
1359: start = last + 1;
1360: more = TRUE;
1361: continue; /* read rest of line, don't print "> " */
1362: }
1363: if (input_line[last] == '\\') { /* line continuation */
1364: start = last;
1365: more = TRUE;
1366: } else
1367: more = FALSE;
1368: } else
1369: more = FALSE;
1370: }
1371: # if !defined(READLINE) && !defined(GNU_READLINE)
1372: if (more && interactive)
1373: PUT_STRING("> ");
1374: # endif
1375: } while (more);
1376: return (0);
1377: }
1378: #endif /* !VMS */
1379:
1380: #ifdef _Windows
1381: /* there is a system like call on MS Windows but it is a bit difficult to
1382: use, so we will invoke the command interpreter and use it to execute the
1383: commands */
1384: static int winsystem(char *s)
1385: {
1386: LPSTR comspec;
1387: LPSTR execstr;
1388: LPSTR p;
1389:
1390: /* get COMSPEC environment variable */
1391: # ifdef WIN32
1392: char envbuf[81];
1393: GetEnvironmentVariable("COMSPEC", envbuf, 80);
1394: if (*envbuf == NUL)
1395: comspec = "\\command.com";
1396: else
1397: comspec = envbuf;
1398: # else
1399: p = GetDOSEnvironment();
1400: comspec = "\\command.com";
1401: while (*p) {
1402: if (!strncmp(p, "COMSPEC=", 8)) {
1403: comspec = p + 8;
1404: break;
1405: }
1406: p += strlen(p) + 1;
1407: }
1408: # endif
1409: /* if the command is blank we must use command.com */
1410: p = s;
1411: while ((*p == ' ') || (*p == '\n') || (*p == '\r'))
1412: p++;
1413: if (*p == NUL) {
1414: WinExec(comspec, SW_SHOWNORMAL);
1415: } else {
1416: /* attempt to run the windows/dos program via windows */
1417: if (WinExec(s, SW_SHOWNORMAL) <= 32) {
1418: /* attempt to run it as a dos program from command line */
1419: execstr = (char *) malloc(strlen(s) + strlen(comspec) + 6);
1420: strcpy(execstr, comspec);
1421: strcat(execstr, " /c ");
1422: strcat(execstr, s);
1423: WinExec(execstr, SW_SHOWNORMAL);
1424: free(execstr);
1425: }
1426: }
1427:
1428: /* regardless of the reality return OK - the consequences of */
1429: /* failure include shutting down Windows */
1430: return (0); /* success */
1431: }
1432: #endif /* _Windows */
1433:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>