Annotation of OpenXM_contrib/gnuplot/command.c, Revision 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>