Esempio n. 1
0
/* Note that we only do io redirection when we get to here - we also
 * postpone some other things until now.  */
static void
docommand(wordlist *wlist)
{
    char *r, *s, *t;
    int nargs;
    int i;
    struct comm *command;
    wordlist *wl, *nextc, *ee, *rwlist;

    if (cp_debug) {
        printf("docommand ");
        wl_print(wlist, stdout);
        putc('\n', stdout);
    }

    /* Do all the things that used to be done by cshpar when the line
     * was read...  */
    wlist = cp_variablesubst(wlist);
    pwlist(wlist, "After variable substitution");

    wlist = cp_bquote(wlist);
    pwlist(wlist, "After backquote substitution");

    wlist = cp_doglob(wlist);
    pwlist(wlist, "After globbing");
    
    pwlist_echo(wlist, "Becomes >");

    if (!wlist || !wlist->wl_word) /*CDHW need to free wlist in second case? CDHW*/
        return;

    /* Now loop through all of the commands given. */
    rwlist = wlist;
    do {
        for (nextc = wlist; nextc; nextc = nextc->wl_next)
            if (eq(nextc->wl_word, cp_csep))
                break;

        /* Temporarily hide the rest of the command... */
        if (nextc && nextc->wl_prev)
            nextc->wl_prev->wl_next = NULL;
        ee = wlist->wl_prev;
        if (ee)
            wlist->wl_prev = NULL;

        if (nextc == wlist) {
            /* There was no text... */
            goto out;
        }

        /* And do the redirection. */
        cp_ioreset();
        for (i = 0; noredirect[i]; i++)
            if (eq(wlist->wl_word, noredirect[i]))
                break;
        if (!noredirect[i]) {
            if (!(wlist = cp_redirect(wlist))) {
                cp_ioreset();
                return;
            }
        }

        /* Get rid of all the 8th bits now... */
        cp_striplist(wlist);

        s = wlist->wl_word;

        /* Look for the command in the command list. */
        for (i = 0; cp_coms[i].co_comname; i++) {
            /* strcmp(cp_coms[i].co_comname, s) ... */
            for (t = cp_coms[i].co_comname, r = s; *t && *r;
		 t++, r++)
                if (*t != *r)
                    break;
            if (!*t && !*r)
                break; 
        }
        
        /* Now give the user-supplied command routine a try... */
        if (!cp_coms[i].co_func && cp_oddcomm(s, wlist->wl_next))
            goto out;

        /* If it's not there, try it as a unix command. */
        if (!cp_coms[i].co_comname) {
            if (cp_dounixcom && cp_unixcom(wlist))
                goto out;
            fprintf(cp_err,"%s: no such command available in %s\n",
		    s, cp_program);
            goto out;

	    /* If it's there but spiceonly, and this is nutmeg, error. */
        } else if (!cp_coms[i].co_func && ft_nutmeg && 
		   (cp_coms[i].co_spiceonly)) {
            fprintf(cp_err,"%s: command available only in spice\n",
                    s);
            goto out;
        }

        /* The command was a valid spice/nutmeg command. */
        command = &cp_coms[i];
        nargs = 0;
        for (wl = wlist->wl_next; wl; wl = wl->wl_next)
            nargs++;
        {
            if (nargs < command->co_minargs) {
		if (command->co_argfn) {
		    (*command->co_argfn) (wlist->wl_next, command);
		} else {
		    fprintf(cp_err, "%s: too few args.\n", s);
		}
            } else if (nargs > command->co_maxargs) {
                fprintf(cp_err, "%s: too many args.\n", s);
            } else {
                (*command->co_func) (wlist->wl_next);
            }
        }

        /* Now fix the pointers and advance wlist. */
    out:        wlist->wl_prev = ee;
        if (nextc) {
            for(wl=wlist; wl->wl_next; wl=wl->wl_next)
                ;
            wl->wl_next = nextc;
            nextc->wl_prev = wl;
            wlist = nextc->wl_next;
        }
    } while (nextc && wlist);

    wl_free(rwlist);

    /* Do periodic sorts of things... */
    cp_periodic();

    cp_ioreset();
    return;
}
Esempio n. 2
0
/* Note that we only do io redirection when we get to here - we also
 * postpone some other things until now.  */
static void
docommand(wordlist *wlist)
{
    wordlist *rwlist;

    if (cp_debug) {
        printf("docommand ");
        wl_print(wlist, stdout);
        putc('\n', stdout);
    }

    /* Do all the things that used to be done by cshpar when the line
     * was read...  */
    wlist = cp_variablesubst(wlist);
    pwlist(wlist, "After variable substitution");

    wlist = cp_bquote(wlist);
    pwlist(wlist, "After backquote substitution");

    wlist = cp_doglob(wlist);
    pwlist(wlist, "After globbing");

    pwlist_echo(wlist, "Becomes >");

    if (!wlist || !wlist->wl_word) /*CDHW need to free wlist in second case? CDHW*/
        return;

    /* Now loop through all of the commands given. */
    rwlist = wlist;
    while (wlist) {

        char *s;
        int i;
        struct comm *command;
        wordlist *nextc, *ee;

        nextc = wl_find(cp_csep, wlist);

        if (nextc == wlist) {   /* skip leading `;' */
            wlist = wlist->wl_next;
            continue;
        }

        /* Temporarily hide the rest of the command... */
        ee = wlist->wl_prev;
        wl_chop(nextc);
        wl_chop(wlist);

        /* And do the redirection. */
        cp_ioreset();
        for (i = 0; noredirect[i]; i++)
            if (eq(wlist->wl_word, noredirect[i]))
                break;
        if (!noredirect[i])
            if ((wlist = cp_redirect(wlist)) == NULL) {
                cp_ioreset();
                return;
            }

        /* Get rid of all the 8th bits now... */
        cp_striplist(wlist);

        s = wlist->wl_word;

        /* Look for the command in the command list. */
        for (i = 0; cp_coms[i].co_comname; i++)
            if (strcasecmp(cp_coms[i].co_comname, s) == 0)
                break;

        command = &cp_coms[i];

        /* Now give the user-supplied command routine a try... */
        if (!command->co_func && cp_oddcomm(s, wlist->wl_next))
            goto out;

        /* If it's not there, try it as a unix command. */
        if (!command->co_comname) {
            if (cp_dounixcom && cp_unixcom(wlist))
                goto out;
            fprintf(cp_err, "%s: no such command available in %s\n",
                    s, cp_program);
            goto out;

            /* If it hasn't been implemented */
        } else if (!command->co_func) {
            fprintf(cp_err, "%s: command is not implemented\n", s);
            goto out;
            /* If it's there but spiceonly, and this is nutmeg, error. */
        } else if (ft_nutmeg && command->co_spiceonly) {
            fprintf(cp_err, "%s: command available only in spice\n", s);
            goto out;
        }

        /* The command was a valid spice/nutmeg command. */
        {
            int nargs = wl_length(wlist->wl_next);
            if (nargs < command->co_minargs) {
                if (command->co_argfn) {
                    command->co_argfn (wlist->wl_next, command);
                } else {
                    fprintf(cp_err, "%s: too few args.\n", s);
                }
            } else if (nargs > command->co_maxargs) {
                fprintf(cp_err, "%s: too many args.\n", s);
            } else {
                command->co_func (wlist->wl_next);
            }
        }

    out:
        wl_append(ee, wlist);
        wl_append(wlist, nextc);

        if (!ee)
            rwlist = wlist;

        wlist = nextc;
    }

    wl_free(rwlist);

    /* Do periodic sorts of things... */
    cp_periodic();

    cp_ioreset();
}
Esempio n. 3
0
wordlist *
cp_lexer(char *string)
{
    int c, d;
    int i, j;
    wordlist *wlist = NULL, *cw = NULL;
    char buf[NEW_BSIZE_SP], linebuf[NEW_BSIZE_SP];
    int paren;
    if (!cp_inp_cur || cp_inp_cur != cp_in)
        cp_inp_cur = cp_in;

    /* prompt for string if none is passed */
    if (!string && cp_interactive) {
        cp_ccon(TRUE);
        prompt();
    }

nloop:
    wlist = cw = NULL;
    i = 0;
    j = 0;
    paren = 0;
    bzero(linebuf, NEW_BSIZE_SP);
    bzero(buf, NEW_BSIZE_SP);
    for (;;) {

        c = cp_readchar(&string, cp_inp_cur);

    gotchar:

        if (string && (c == ESCAPE))
            continue;

        if ((c != EOF) && (c != ESCAPE))
            linebuf[j++] = (char) c;

        if (c != EOF)
            numeofs = 0;

        if (i == NEW_BSIZE_SP - 1) {
            fprintf(cp_err, "Warning: word too long.\n");
            c = ' ';
        }

        if (j == NEW_BSIZE_SP - 1) {
            fprintf(cp_err, "Warning: line too long.\n");
            if (cp_bqflag)
                c = EOF;
            else
                c = '\n';
        }

        if (c != EOF)           /* Don't need to do this really. */
            c = strip(c);

        if ((c == '\\' && DIR_TERM != '\\') || (c == '\026') /* ^V */ ) {
            c = quote(cp_readchar(&string, cp_inp_cur));
            linebuf[j++] = (char) strip(c);
        }

        if ((c == '\n') && cp_bqflag)
            c = ' ';

        if ((c == EOF) && cp_bqflag)
            c = '\n';

        if ((c == cp_hash) && !cp_interactive && (j == 1)) {
            wl_free(wlist);
            wlist = cw = NULL;
            if (string)
                return NULL;
            while (((c = cp_readchar(&string, cp_inp_cur)) != '\n') && (c != EOF))
                ;
            goto nloop;
        }

        if ((c == '(') || (c == '[')) /* MW. Nedded by parse() */
            paren++;
        else if ((c == ')') || (c == ']'))
            paren--;

        switch (c) {

        case ' ':
        case '\t':
            if (i > 0)
                newword;
            break;

        case '\n':
            if (i) {
                buf[i] = '\0';
                newword;
            }
            if (!cw)
                append(NULL);
            goto done;

        case '\'':
            while (((c = cp_readchar(&string, cp_inp_cur)) != '\'') &&
                   (i < NEW_BSIZE_SP - 1))
            {
                if ((c == '\n') || (c == EOF) || (c == ESCAPE))
                    goto gotchar;
                buf[i++] = (char) quote(c);
                linebuf[j++] = (char) c;
            }
            linebuf[j++] = '\'';
            break;

        case '"':
        case '`':
            d = c;
            buf[i++] = (char) d;
            while (((c = cp_readchar(&string, cp_inp_cur)) != d) &&
                   (i < NEW_BSIZE_SP - 2))
            {
                if ((c == '\n') || (c == EOF) || (c == ESCAPE))
                    goto gotchar;
                if (c == '\\') {
                    linebuf[j++] = (char) c;
                    c = cp_readchar(&string, cp_inp_cur);
                    buf[i++] = (char) quote(c);
                    linebuf[j++] = (char) c;
                } else {
                    buf[i++] = (char) c;
                    linebuf[j++] = (char) c;
                }
            }
            buf[i++] = (char) d;
            linebuf[j++] = (char) d;
            break;

        case '\004':
        case EOF:
            if (cp_interactive && !cp_nocc && !string) {

                if (j == 0) {
                    if (cp_ignoreeof && (numeofs++ < 23)) {
                        fputs("Use \"quit\" to quit.\n", stdout);
                    } else {
                        fputs("quit\n", stdout);
                        
                       // return ;
                       
                       // cp_doquit();
                    }
                    append(NULL);
                    goto done;
                }

                // cp_ccom doesn't mess wlist, read only access to wlist->wl_word
                cp_ccom(wlist, buf, FALSE);
                wl_free(wlist);
                (void) fputc('\r', cp_out);
                prompt();
                for (j = 0; linebuf[j]; j++)
#ifdef TIOCSTI
                    (void) ioctl(fileno(cp_out), TIOCSTI, linebuf + j);
#else
                fputc(linebuf[j], cp_out);  /* But you can't edit */
#endif
                wlist = cw = NULL;
                goto nloop;
            }

            /* EOF during a source */
            if (cp_interactive) {
                fputs("quit\n", stdout);
                cp_doquit();
                append(NULL);
                goto done;
            }

            wl_free(wlist);
            return NULL;

        case ESCAPE:
            if (cp_interactive && !cp_nocc) {
                fputs("\b\b  \b\b\r", cp_out);
                prompt();
                for (j = 0; linebuf[j]; j++)
#ifdef TIOCSTI
                    (void) ioctl(fileno(cp_out), TIOCSTI, linebuf + j);
#else
                fputc(linebuf[j], cp_out);  /* But you can't edit */
#endif
                // cp_ccom doesn't mess wlist, read only access to wlist->wl_word
                cp_ccom(wlist, buf, TRUE);
                wl_free(wlist);
                wlist = cw = NULL;
                goto nloop;
            }
            goto ldefault;

        case ',':
            if ((paren < 1) && (i > 0)) {
                newword;
                break;
            }
            goto ldefault;

        case ';':  /* CDHW semicolon inside parentheses is part of expression */
            if (paren > 0) {
                buf[i++] = (char) c;
                break;
            }
            goto ldefault;

        case '&':  /* va: $&name is one word */
            if ((i >= 1) && (buf[i-1] == '$') && (c == '&')) {
                buf[i++] = (char) c;
                break;
            }
            goto ldefault;

        case '<':
        case '>':  /* va: <=, >= are unbreakable words */
            if (string)
                if ((i == 0) && (*string == '=')) {
                    buf[i++] = (char) c;
                    break;
                }
            goto ldefault;

        default:
            /* We have to remember the special case $<
             * here
             */
        ldefault:
            if ((cp_chars[c] & CPC_BRL) && (i > 0))
                if ((c != '<') || (buf[i-1] != '$'))
                    newword;
            buf[i++] = (char) c;
            if (cp_chars[c] & CPC_BRR)
                if ((c != '<') || (i < 2) || (buf[i-2] != '$'))
                    newword;
        }
    }

done:
    if (wlist->wl_word)
        pwlist_echo(wlist, "Command>");
    return wlist;
}