[BACK]Return to command.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

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>