eval.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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
* 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 1993 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
* 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, /* backslash */
};
/* return code from most recently executed command */
int EV_retcode;
int EV_backquotes;
int Lasttok;
char *
special_char(c, instr)
register int c;
{
char *strchr();
int c2;
if ((char)c == '2')
{
/* it would unget c not c2. abs */
if ((char)c2 != '>')
return(NULL);
}
}
int flags;
{
register int c;
register int tok;
bool done;
when special (one case) instead of
in all other cases. abs */
EV_retcode = 0;
/* skip leading white space */
while (isspace(c))
if (c == '#') {
/*
* skip everything until end of line
*/
;
}
}
/* handler `` at beginning of line if in GROUP mode */
}
#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
register char *p;
char *strchr();
/* while (!(p = strchr(spchars, c))) {
abs */
while(!(p = special_char(c, instr))) {
break;
}
}
if (done)
break;
/* single | and & are correct here */
tok = !!c;
else {
#ifdef _DEBUG2
#endif
}
switch (tok) {
case ET_EOF:
break;
case ET_WORD:
break;
case ET_DQUOTE:
break;
case ET_SQUOTE:
break;
case ET_BSLASH:
/*
* 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]))
break;
case ET_BQUOTE:
}
}
else
}
else {
}
break;
case ET_DOLLAR:
else
break;
case ET_NEWLINE:
case ET_SPACE:
case ET_TAB:
else
break;
case ET_OSQUIG:
case ET_CSQUIG:
}
}
break;
case ET_PIPE:
case ET_AMPERSAND:
case ET_SEMI:
case ET_LTHAN:
case ET_GTHAN:
register int oldc;
oldc = c;
}
}
}
else
break;
case ET_TWO:
}
}
}
else
break;
}
if (done)
break;
}
if (c)
#ifdef _DEBUG2
}
#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 flags;
{
register char *p;
register int c;
char *expand();
int evalagain;
extern bool Doublevars;
if (Doublevars == TRUE)
else {
}
else {
}
}
while (c != '}') {
}
}
else {
}
if (c)
}
if (evalagain) {
/*
* if the "contents" of the variable should
* be evaluated before passing it to outstr ...
*/
free(p);
p = (char *)NULL;
}
else {
/*
* simply put the variable's contents into outstr
*/
free(p);
p = (char *)NULL;
}
return SUCCESS;
}
return FAIL;
}
static char *
int flags;
{
register char *p;
return NULL;
}
return p;
}
static
int flags;
{
int argc;
bool doit;
int conditional = 0;
int if_elif = 0;
bool skip;
bool piped;
bool special;
#ifdef _DEBUG2
#endif
for (argc = 0; ; ) {
conditional = 0;
if (argc == 1) {
/*
* determine whether we've found an
*/
if_elif = 0;
#ifdef _DEBUG2
#endif
switch(argv[0][0]) {
case 'e': /* else, elif */
conditional = 1;
conditional = 1;
if_elif = 1;
}
break;
case 'i': /* if */
conditional = 1;
if_elif = 1;
}
break;
case 't': /* then */
conditional = 1;
break;
}
if (conditional) {
int a, nonwhite, start_look;
char *cp;
char ch;
/*
* (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).
*/
/*
* is done via built-ins ... don't allow
*/
nonwhite = 1;
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];
mess_lock();
in_an_if = 0;
}
break;
}
/*
* not a space, tab, new-line
* or semi-colon ......
*/
nonwhite = 0;
}
}
}
}
switch (Lasttok) {
case ET_EOF:
case ET_BQUOTE:
break;
case ET_PIPE:
{
if (altstdout) {
#ifdef _DEBUG2
#endif
}
}
break;
case ET_AMPERSAND:
break;
case ET_SEMI:
break;
case ET_LTHAN:
{
register char *p;
}
else
free(p);
p = (char *)NULL;
}
break;
case ET_GTHAN:
{
register char *p;
if (altstdout) {
#ifdef _DEBUG2
#endif
}
else
free(p);
p = (char *)NULL;
}
break;
case ET_TWO:
{
register char *p;
if (altstderr) {
#ifdef _DEBUG2
#endif
}
else
free(p);
p = (char *)NULL;
}
break;
/* OR symbol */
break;
/* AND symbol */
case ET_AMPERSAND + DOUBLE:
break;
/* semicolon (twice in a row) */
break;
/* here document */
break;
}
if (special) {
}
register int n;
{
/*
* if there is a syntax error in the
* conditional statement then terminate
* evaluation
*/
}
for (n = 0; n < argc; n++)
if (argv[n]) { /* ehr3 */
}
argc = 0;
if (piped) {
}
else {
if (altstdout)
}
if (altstderr)
{
}
break;
}
}
}