summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fmli/sys/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/fmli/sys/eval.c')
-rw-r--r--usr/src/cmd/fmli/sys/eval.c713
1 files changed, 0 insertions, 713 deletions
diff --git a/usr/src/cmd/fmli/sys/eval.c b/usr/src/cmd/fmli/sys/eval.c
deleted file mode 100644
index 7d7bf7982b..0000000000
--- a/usr/src/cmd/fmli/sys/eval.c
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef CACA
-#define _DEBUG2 1
-int _Debug=4;
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include "wish.h"
-#include "eval.h"
-#include "terror.h"
-#include "message.h"
-#include "moremacros.h"
-#include "interrupt.h"
-
-#define MAXARGS 64
-
-/* NOTE!!! the following flags compete for bits with
- * the EV_**** flags in inc/eval.h Make sure
- * there is no overlap.
- */
-#define IN_DQ 1
-#define IN_SQ 2
-#define IN_BQ 4
-#define IN_SQUIG 8
-#define FROM_BQ 16
-
-/*
- * list of "special" characters, and flags in which they are not
- * treated as special. NOTE that EV_SQUIG flag is opposite all
- * others. set it in nflags if {} ARE to be treated as special.
- */
-static char spchars[] = "\"'\\`$\n \t{}|&;<>2";
-/*static char spchars[] = "\"'\\`$\n \t{}|&;<>";
-abs */
-static int nflags[] = {
- FROM_BQ | IN_SQ, /* double quote */
- FROM_BQ | IN_DQ, /* single quote */
- FROM_BQ, /* backslash */
- FROM_BQ | IN_SQ, /* back quote */
- FROM_BQ | IN_SQ, /* dollar sign */
- IN_SQUIG | IN_SQ | IN_DQ, /* new line */
- FROM_BQ | IN_SQ | IN_DQ | EV_GROUP, /* space */
- FROM_BQ | IN_SQ | IN_DQ | EV_GROUP, /* tab */
- FROM_BQ | IN_SQUIG | IN_SQ | IN_DQ | IN_BQ | EV_SQUIG, /* open squig */
- FROM_BQ | IN_SQ | IN_DQ | IN_BQ | EV_SQUIG, /* close squig */
- FROM_BQ | IN_SQ | IN_DQ | EV_GROUP, /* pipe symbol */
- FROM_BQ | IN_SQ | IN_DQ | EV_GROUP, /* ampersand */
- FROM_BQ | IN_SQ | IN_DQ | EV_GROUP, /* semicolon */
- FROM_BQ | IN_SQ | IN_DQ | EV_GROUP, /* less than */
- FROM_BQ | IN_SQ | IN_DQ | EV_GROUP /* greater than */
- ,FROM_BQ | IN_SQ | IN_DQ | EV_GROUP /* digit two */
-};
-
-/* return code from most recently executed command */
-int EV_retcode;
-int EV_backquotes;
-int Lasttok;
-
-extern int in_an_if; /* (in an if statement) see evfuncs.c */
-
-static int eval_dollar();
-static void eval_backquote();
-
-char *
-special_char(c, instr)
-register int c;
-IOSTRUCT *instr;
-{
- char *strchr();
- int c2;
-
- if ((char)c == '2')
- {
- c2 = getac(instr);
- if(c2 || instr->flags & EV_USE_FP) /* the other case: EV_USE_STRING */
- ungetac(c2, instr); /* and c2 = EndOfString. don't unget cause */
- /* it would unget c not c2. abs */
- if ((char)c2 != '>')
- return(NULL);
- }
- return(strchr(spchars, c));
-}
-
-
-int
-eval(instr, outstr, flags)
-IOSTRUCT *instr;
-IOSTRUCT *outstr;
-int flags;
-{
- register int c;
- register int tok;
- bool done;
-
- flags ^= EV_SQUIG; /* flip flag so only have to set it
- when special (one case) instead of
- in all other cases. abs */
- if (!(flags & IN_BQ))
- EV_retcode = 0;
- EV_backquotes = FALSE;
- c = getac(instr);
- /* skip leading white space */
- if (flags & (EV_TOKEN | EV_GROUP)) {
- while (isspace(c))
- c = getac(instr);
- if (c == '#') {
- /*
- * skip everything until end of line
- */
- while ((c = getac(instr)) && c != '\n' && c != EOF)
- ;
- }
- }
- /* handler `` at beginning of line if in GROUP mode */
- if ((flags & EV_GROUP) && c == '`') {
- eval_backquote(instr, outstr, flags);
- io_flags(instr, io_flags(instr, 0) & ~FROM_BQ);
- c = getac(instr);
- }
-#ifdef _DEBUG2
-/*
- if ((flags & EV_TOKEN) && (instr->flags & EV_USE_STRING)) {
- _debug2(stderr, "input is '%.*s'\n", instr->mu.str.count - instr->mu.str.pos, instr->mu.str.val + instr->mu.str.pos);
- }
-*/
-#endif
-
- Lasttok = tok = ET_EOF;
- for (done = FALSE; c; c = getac(instr)) {
- register char *p;
- char *strchr();
-
-/* while (!(p = strchr(spchars, c))) {
-abs */
- while(!(p = special_char(c, instr))) {
- Lasttok = ET_WORD;
- putac(c, outstr);
- if (!(c = getac(instr))) {
- done = TRUE;
- break;
- }
- }
- if (done)
- break;
- /* single | and & are correct here */
- if ((instr->flags | flags) & nflags[tok = p - spchars])
- tok = !!c;
- else {
- tok += ET_DQUOTE;
-#ifdef _DEBUG2
- _debug2(stderr, "eval: got special char 0x%x\n", tok);
-#endif
- }
- switch (tok) {
- case ET_EOF:
- done = TRUE;
- break;
- case ET_WORD:
- Lasttok = tok;
- putac(c, outstr);
- break;
- case ET_DQUOTE:
- flags ^= IN_DQ;
- if (!(flags & EV_TOKEN))
- putac(c, outstr);
- break;
- case ET_SQUOTE:
- flags ^= IN_SQ;
- if (!(flags & EV_TOKEN))
- putac(c, outstr);
- break;
- case ET_BSLASH:
- c = getac(instr);
- /*
- * if (not tokenizing or if we're in quotes and the
- * next character is not special, leave backslash
- * there
- * else
- * remove it (don't copy to output)
- */
- if (!(flags & EV_TOKEN) || (flags & (IN_SQ | IN_DQ)) && (!(p = strchr(spchars, c)) || (instr->flags | flags) & nflags[p - spchars]))
- putac('\\', outstr);
- putac(c, outstr);
- break;
- case ET_BQUOTE:
- if (flags & EV_TOKEN) {
- if (flags & IN_BQ) {
- if (Lasttok == ET_EOF) {
- putac(c, outstr);
- c = getac(instr);
- Lasttok = tok;
- }
- done = TRUE;
- }
- else
- eval_backquote(instr, outstr, flags);
- }
- else {
- flags ^= IN_BQ;
- putac(c, outstr);
- }
- EV_backquotes = TRUE;
- break;
- case ET_DOLLAR:
- if (flags & EV_TOKEN)
- eval_dollar(instr, outstr, flags);
- else
- putac(c, outstr);
- break;
- case ET_NEWLINE:
- case ET_SPACE:
- case ET_TAB:
- Lasttok = ET_WORD;
- if ((flags & EV_GROUP) && (flags & IN_BQ))
- putac(c, outstr);
- else
- done = TRUE;
- break;
- case ET_OSQUIG:
- case ET_CSQUIG:
- putac(c, outstr);
- if (flags & EV_GROUP)
- flags ^= IN_SQUIG;
- else if (flags & EV_TOKEN) {
- if (Lasttok == ET_EOF) {
- c = getac(instr);
- Lasttok = tok;
- }
- done = TRUE;
- }
- break;
- case ET_PIPE:
- case ET_AMPERSAND:
- case ET_SEMI:
- case ET_LTHAN:
- case ET_GTHAN:
- if (flags & IN_BQ) {
- if (Lasttok == ET_EOF) {
- register int oldc;
-
- putac(c, outstr);
- oldc = c;
- if ((c = getac(instr)) == oldc) {
- putac(c, outstr);
- c = getac(instr);
- tok += DOUBLE;
- }
- Lasttok = tok;
- }
- done = TRUE;
- }
- else
- putac(c, outstr);
- break;
- case ET_TWO:
- if (flags & IN_BQ) {
- if (Lasttok == ET_EOF) {
- putac(c, outstr);
- c = getac(instr); /* gets > known to follow 2 */
- putac(c, outstr);
- if ((c = getac(instr)) == '>') {
- putac(c, outstr);
- c = getac(instr);
- tok += DOUBLE;
- }
- Lasttok = tok;
- }
- done = TRUE;
- }
- else
- putac(c, outstr);
- break;
- }
- if (done)
- break;
- Lasttok = ET_WORD;
- }
- if (c)
- ungetac(c, instr);
-#ifdef _DEBUG2
- if (flags & EV_TOKEN) {
- _debug2(stderr, "eval -> '%s'\n", io_ret_string(outstr));
- _debug2(stderr, "eval returning 0x%x\n", Lasttok);
- }
-#endif
-
- return Lasttok;
-}
-
-/*
- * NOTE:
- *
- * In pre-4.0 releases of FMLI, the contents of environment variables
- * (after expansion) were put back into the input string for further
- * evaluation (lets call it "double evaluation").
- *
- * To remain backwards compatable, the global variable "Doublevars"
- * will be set to TRUE if double evaluation should be performed on
- * ALL environment variables.
- *
- * If Doublevars == FALSE, then only evaluate the "contents" of the
- * variable if a "!" follows "$" (i.e., the "new" convention for double
- * evaluation is "$!VARNAME").
- *
- */
-/*ARGSUSED*/
-static int
-eval_dollar(instr, outstr, flags)
-IOSTRUCT *instr;
-IOSTRUCT *outstr;
-int flags;
-{
- register char *p;
- register int c;
- register IOSTRUCT *iop;
- char *expand();
- int evalagain;
- extern bool Doublevars;
-
- iop = io_open(EV_USE_STRING, NULL);
- putac('$', iop);
- if (Doublevars == TRUE)
- evalagain = TRUE;
- else {
- if ((c = getac(instr)) == '!') {
- evalagain = TRUE;
- }
- else {
- evalagain = FALSE;
- ungetac(c, instr);
- }
- }
- if ((c = getac(instr)) == '{') {
- while (c != '}') {
- putac(c, iop);
- c = getac(instr);
- }
- putac(c, iop);
- }
- else {
- while (isalpha(c) || isdigit(c) || c == '_') {
- putac(c, iop);
- c = getac(instr);
- }
- if (c)
- ungetac(c, instr);
- }
- if (p = expand(io_ret_string(iop))) {
- io_clear(iop);
- if (evalagain) {
- /*
- * if the "contents" of the variable should
- * be evaluated before passing it to outstr ...
- */
- putastr(p, iop);
- free(p);
- p = (char *)NULL;
- io_seek(iop, 0);
- io_push(instr, iop); /* push it back in instr */
- }
- else {
- /*
- * simply put the variable's contents into outstr
- */
- putastr(p, outstr);
- free(p);
- p = (char *)NULL;
- io_close(iop);
- }
- return SUCCESS;
- }
- return FAIL;
-}
-
-static char *
-eval_token(instr, flags)
-IOSTRUCT *instr;
-int flags;
-{
- register char *p;
- static IOSTRUCT *tmp;
-
- if (instr == NULL) {
- io_close(tmp);
- return NULL;
- }
- if (tmp == NULL)
- tmp = io_open(EV_USE_STRING, NULL);
- (void) eval(instr, tmp, flags);
- p = io_string(tmp);
- io_seek(tmp, 0);
- return p;
-}
-
-static void
-eval_backquote(instr, outstr, flags)
-IOSTRUCT *instr;
-IOSTRUCT *outstr;
-int flags;
-{
- int argc;
- char *argv[MAXARGS];
- bool doit;
- int conditional = 0;
- int if_elif = 0;
- bool skip;
- bool piped;
- bool special;
- IOSTRUCT *mystdin;
- IOSTRUCT *mystdout;
- IOSTRUCT *altstdout;
- IOSTRUCT *altstderr;
-
-#ifdef _DEBUG2
- _debug2(stderr, "eval_backquote\n");
-#endif
- mystdin = io_open(EV_USE_STRING, NULL);
- mystdout = io_open(EV_USE_STRING, NULL);
- altstdout = NULL;
- altstderr = NULL;
- doit = skip = piped = special = FALSE;
-
- for (argc = 0; ; ) {
- conditional = 0;
- argv[argc++] = eval_token(instr, EV_TOKEN | IN_BQ);
-
- if (argc == 1) {
- /*
- * determine whether we've found an
- * if/then/else/elif statement
- */
- if_elif = 0;
-
-#ifdef _DEBUG2
- _debug2(stderr, "argv[0]=\"%s\"\n\r", argv[0]);
-#endif
-
- switch(argv[0][0]) {
- case 'e': /* else, elif */
- if (!strcmp(argv[0], "else"))
- conditional = 1;
- else if (!strcmp(argv[0], "elif")) {
- conditional = 1;
- if_elif = 1;
- }
- break;
- case 'i': /* if */
- if (argv[0][1] == 'f' && argv[0][2] == '\0') {
- conditional = 1;
- if_elif = 1;
- }
- break;
- case 't': /* then */
- if (!strcmp(argv[0], "then"))
- conditional = 1;
- break;
- }
-
- if (conditional) {
- int a, nonwhite, start_look;
- char *cp;
- char ch;
-
- /*
- * Force call to if/then/else/elif built-in
- * (no arguments) ... Don't modify the input
- * string here, just put a semi-colon in the
- * "argv" array and set Lasttok (last token
- * received) to ET_SEMI (semi-colon).
- */
- argv[argc++] = strsave(";");
- Lasttok = ET_SEMI;
-
-
- /*
- * Though the implementation of if/then/else
- * is done via built-ins ... don't allow
- * semi-colons after if/then/else/elif !!
- */
- start_look = instr->mu.str.pos;
- cp = instr->mu.str.val + start_look;
- nonwhite = 1;
- for (a = 0; a < instr->mu.str.count - start_look + 1; a++) {
- ch = *(cp + a);
-
- if (ch == '\n' )
- break;
- else if (ch == ';') {
- /*
- * If all you've seen is
- * white-space then produce
- * an error message
- */
- if (nonwhite) {
- char errbuf[100];
-
- sprintf(errbuf, "Syntax error - \";\" found after \"%s\"", argv[0]);
- mess_temp(errbuf);
- mess_lock();
- Lasttok = ET_EOF;
- in_an_if = 0;
- }
- break;
- }
- else if (ch != '\t' && ch != ' ') {
- /*
- * not a space, tab, new-line
- * or semi-colon ......
- */
- nonwhite = 0;
- }
- }
- }
- }
-
- switch (Lasttok) {
- case ET_EOF:
- case ET_BQUOTE:
- special = doit = TRUE;
- break;
- case ET_PIPE:
- {
- register FILE *fp;
- FILE *tempfile();
-
- if (altstdout) {
-#ifdef _DEBUG2
- _debug2(stderr, "PIPE and > in same eval command\n");
-#endif
- io_close(altstdout);
- altstdout = NULL;
- }
- if (fp = tempfile(NULL, "w+"))
- altstdout = io_open(EV_USE_FP, fp);
- special = doit = piped = TRUE;
- }
- break;
- case ET_AMPERSAND:
- break;
- case ET_SEMI:
- special = doit = TRUE;
- break;
- case ET_LTHAN:
- {
- register FILE *fp;
- register char *p;
-
- special = TRUE;
- p = eval_token(instr, EV_TOKEN | IN_BQ);
- if (fp = fopen(p, "r")) {
- io_close(mystdin);
- mystdin = io_open(EV_USE_FP, fp);
- }
- else
- warn(NOPEN, p);
- free(p);
- p = (char *)NULL;
- }
- break;
- case ET_GTHAN:
- case ET_GTHAN + DOUBLE: /* append symbol */
- {
- register FILE *fp;
- register char *p;
- int savetok=Lasttok;
- special = TRUE;
- if (altstdout) {
-#ifdef _DEBUG2
- _debug2(stderr, "2 >'s in eval command\n");
-#endif
- io_close(altstdout);
- }
- p = eval_token(instr, EV_TOKEN | IN_BQ);
- if (fp = fopen(p, (savetok & DOUBLE)?"a":"w"))
- altstdout = io_open(EV_USE_FP, fp);
- else
- warn(NOPEN, p);
- free(p);
- p = (char *)NULL;
- }
- break;
- case ET_TWO:
- case ET_TWO + DOUBLE: /* append stderr symbol (2>>)*/
- {
- register FILE *fp;
- register char *p;
- int savetok=Lasttok;
-
- special = TRUE;
- if (altstderr) {
-#ifdef _DEBUG2
- _debug2(stderr, "2 >'s in eval command\n");
-#endif
- io_close(altstderr);
- altstderr = NULL;
- }
- p = eval_token(instr, EV_TOKEN | IN_BQ);
- if (fp = fopen(p, (savetok & DOUBLE) ?"a":"w"))
- altstderr = io_open(EV_USE_FP, fp);
- else
- warn(NOPEN, p);
- free(p);
- p = (char *)NULL;
- }
- break;
- /* OR symbol */
- case ET_PIPE + DOUBLE:
- special = doit = TRUE;
- break;
- /* AND symbol */
- case ET_AMPERSAND + DOUBLE:
- special = doit = TRUE;
- break;
- /* semicolon (twice in a row) */
- case ET_SEMI + DOUBLE:
- special = doit = TRUE;
- break;
- /* here document */
- case ET_LTHAN + DOUBLE:
- break;
-
- }
- if (special) {
- free(argv[--argc]);
- argv[argc] = (char *)NULL;
- special = FALSE;
- }
- if (doit || argc >= MAXARGS - 1) {
- register int n;
-
- doit = FALSE;
- if (!skip && !Cur_intr.skip_eval && argc > 0) /* abs */
- {
- argv[argc] = NULL;
- EV_retcode = evalargv(argc, argv, mystdin,
- altstdout ? altstdout : mystdout,
- altstderr);
- /*
- * if there is a syntax error in the
- * conditional statement then terminate
- * evaluation
- */
- if (conditional && (EV_retcode == FAIL))
- Lasttok = ET_EOF;
- }
- skip = (EV_retcode && Lasttok == ET_AMPERSAND + DOUBLE)
- || (!EV_retcode && Lasttok == ET_PIPE + DOUBLE);
- for (n = 0; n < argc; n++)
- if (argv[n]) { /* ehr3 */
- free(argv[n]);
- argv[n] = (char *)NULL;
- }
- argc = 0;
- io_close(mystdin);
- if (piped) {
- mystdin = altstdout;
- io_seek(mystdin, 0);
- piped = FALSE;
- }
- else {
- mystdin = io_open(EV_USE_STRING, NULL);
- if (altstdout)
- io_close(altstdout);
- }
- if (altstderr)
- {
- io_close(altstderr);
- altstderr = NULL;
- }
- altstdout = NULL;
- if (Lasttok == ET_EOF || Lasttok == ET_BQUOTE)
- break;
- }
- }
- if ((argc = unputac(mystdout)) && argc != '\n')
- putac(argc, mystdout);
- if (flags & EV_GROUP)
- putac('\n', mystdout);
- io_seek(mystdout, 0);
- io_flags(mystdout, io_flags(mystdout, 0) | FROM_BQ);
- io_push(instr, mystdout);
-}