Beispiel #1
0
bool
cp_istrue(wordlist *wl)
{
    struct dvec *v;
    struct pnode *names;
    bool rv;

    /* First do all the csh-type stuff here... */
    wl = wl_copy(wl);
    wl = cp_variablesubst(wl);
    wl = cp_bquote(wl);
    cp_striplist(wl);

    names = ft_getpnames(wl, TRUE);
    wl_free(wl);

    v = ft_evaluate(names);

    rv = !vec_iszero(v);

    /* va: garbage collection for v, if pnode names is no simple value */
    if (names->pn_value == NULL && v != NULL)
        vec_free(v);
    free_pnode(names); /* free also v, if pnode names is simple value */

    return rv;
}
Beispiel #2
0
wordlist *process(wordlist *wlist)
{

    wlist = cp_variablesubst(wlist);
    wlist = cp_bquote(wlist);
    wlist = cp_doglob(wlist);
    return (wlist);

}
Beispiel #3
0
bool
cp_istrue(wordlist *wl)
{
    int i;
    struct dvec *v;
    struct pnode *pn;

/* fprintf(stderr, "isTRUE: "); wl_print(wl, stderr); fprintf(stderr, "\n"); */
    /* First do all the csh-type stuff here... */
    wl = wl_copy(wl);
    wl = cp_variablesubst(wl);
    wl = cp_bquote(wl);
    cp_striplist(wl);

    pn = ft_getpnames(wl, TRUE);
    wl_free(wl);
    v = ft_evaluate(pn);

    /* It makes no sense to say while (all), but what the heck... */
    while (v) {
        if (isreal(v)) {
            for (i = 0; i < v->v_length; i++)
                if (v->v_realdata[i] != 0.0) {
		   free_pnode(pn);
                   return (TRUE);
		}
        } else {
            for (i = 0; i < v->v_length; i++)
                if ((realpart(&v->v_compdata[i]) != 0.0) ||
                    (imagpart(&v->v_compdata[i]) != 0.0)) {
		    free_pnode(pn);
                    return (TRUE);
		}
        }
        v = v->v_link2;
    }
   free_pnode(pn);
   return (FALSE);
}
Beispiel #4
0
bool
cp_istrue(wordlist *wl)
{
    int i;
    struct dvec *v;
    struct pnode *names;

    /* First do all the csh-type stuff here... */
    wl = wl_copy(wl);
    wl = cp_variablesubst(wl);
    wl = cp_bquote(wl);
    cp_striplist(wl);

    names = ft_getpnames(wl, TRUE);
    wl_free(wl);

    v = ft_evaluate(names);

    for (; v; v = v->v_link2)
        if (isreal(v)) {
            for (i = 0; i < v->v_length; i++)
                if (v->v_realdata[i] != 0.0) {
                    free_pnode(names);
                    return (TRUE);
                }
        } else {
            for (i = 0; i < v->v_length; i++)
                if ((realpart(v->v_compdata[i]) != 0.0) ||
                    (imagpart(v->v_compdata[i]) != 0.0)) {
                    free_pnode(names);
                    return (TRUE);
                }
        }

    free_pnode(names);
    return (FALSE);
}
Beispiel #5
0
/* Execute a block.  There can be a number of return values from this routine.
 *  NORMAL indicates a normal termination
 *  BROKEN indicates a break -- if the caller is a breakable loop,
 *      terminate it, otherwise pass the break upwards
 *  CONTINUED indicates a continue -- if the caller is a continuable loop,
 *      continue, else pass the continue upwards
 *  Any other return code is considered a pointer to a string which is
 *      a label somewhere -- if this label is present in the block,
 *      goto it, otherwise pass it up. Note that this prevents jumping
 *      into a loop, which is good.
 *
 * Note that here is where we expand variables, ``, and globs for
 * controls.
 *
 * The 'num' argument is used by break n and continue n.  */
static char *
doblock(struct control *bl, int *num)
{
    struct control *ch, *cn = NULL;
    wordlist *wl, *wltmp;
    char *i, *wlword;
    int nn;

    nn = *num + 1; /*CDHW this is a guess... CDHW*/

    switch (bl->co_type) {
    case CO_WHILE:
        if (!bl->co_children) {
            fprintf(cp_err, "Warning: Executing empty 'while' block.\n");
            fprintf(cp_err, "         (Use a label statement as a no-op to suppress this warning.)\n");
        }
        while (bl->co_cond && cp_istrue(bl->co_cond)) {
            if (!bl->co_children) cp_periodic();  /*CDHW*/
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                switch (*i) {

                case NORMAL:
                    break;

                case BROKEN:    /* Break. */
                    if (nn < 2) {
                        return (NORMAL_STR);
                    } else {
                        *num = nn - 1;
                        return (BROKEN_STR);
                    }

                case CONTINUED: /* Continue. */
                    if (nn < 2) {
                        cn = NULL;
                        break;
                    } else {
                        *num = nn - 1;
                        return (CONTINUED_STR);
                    }

                default:
                    cn = findlabel(i, bl->co_children);
                    if (!cn)
                        return (i);
                }
            }
        }
        break;

    case CO_DOWHILE:
        do {
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                switch (*i) {

                case NORMAL:
                    break;

                case BROKEN:    /* Break. */
                    if (nn < 2) {
                        return (NORMAL_STR);
                    } else {
                        *num = nn - 1;
                        return (BROKEN_STR);
                    }

                case CONTINUED: /* Continue. */
                    if (nn < 2) {
                        cn = NULL;
                        break;
                    } else {
                        *num = nn - 1;
                        return (CONTINUED_STR);
                    }

                default:
                    cn = findlabel(i, bl->co_children);
                    if (!cn)
                        return (i);
                }
            }
        } while (bl->co_cond && cp_istrue(bl->co_cond));
        break;

    case CO_REPEAT:
        if (!bl->co_children) {
            fprintf(cp_err, "Warning: Executing empty 'repeat' block.\n");
            fprintf(cp_err, "         (Use a label statement as a no-op to suppress this warning.)\n");
        }
        if (!bl->co_timestodo) bl->co_timestodo = bl->co_numtimes;
        /*bl->co_numtimes: total repeat count
          bl->co_numtimes = -1: repeat forever
          bl->co_timestodo: remaining repeats*/
        while ((bl->co_timestodo > 0) ||
               (bl->co_timestodo == -1)) {
            if (!bl->co_children) cp_periodic();  /*CDHW*/
            if (bl->co_timestodo != -1) bl->co_timestodo--;
            /* loop through all stements inside rpeat ... end */
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                switch (*i) {

                case NORMAL:
                    break;

                case BROKEN:    /* Break. */
                    /* before leaving repeat loop set remaining timestodo to 0 */
                    bl->co_timestodo = 0;
                    if (nn < 2) {
                        return (NORMAL_STR);
                    } else {
                        *num = nn - 1;
                        return (BROKEN_STR);
                    }

                case CONTINUED: /* Continue. */
                    if (nn < 2) {
                        cn = NULL;
                        break;
                    } else {
                        /* before leaving repeat loop set remaining timestodo to 0 */
                        bl->co_timestodo = 0;
                        *num = nn - 1;
                        return (CONTINUED_STR);
                    }

                default:
                    cn = findlabel(i, bl->co_children);

                    if (!cn) {
                        /* no label found inside repeat loop:
                           before leaving loop set remaining timestodo to 0 */
                        bl->co_timestodo = 0;
                        return (i);
                    }
                }
            }
        }
        break;

    case CO_IF:
        if (bl->co_cond && cp_istrue(bl->co_cond)) {
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                if (*i > 2) {
                    cn = findlabel(i,
                                   bl->co_children);
                    if (!cn)
                        return (i);
                    else
                        tfree(i);
                } else if (*i != NORMAL) {
                    *num = nn;
                    return (i);
                }
            }
        } else {
            for (ch = bl->co_elseblock; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                if (*i > 2) {
                    cn = findlabel(i, bl->co_elseblock);
                    if (!cn)
                        return (i);
                } else if (*i != NORMAL) {
                    *num = nn;
                    return (i);
                }
            }
        }
        break;

    case CO_FOREACH:
        wltmp = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(bl->co_text))));
        for (wl = wltmp; wl; wl = wl->wl_next) {
            cp_vset(bl->co_foreachvar, CP_STRING, wl->wl_word);
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                switch (*i) {

                case NORMAL:
                    break;

                case BROKEN:    /* Break. */
                    if (nn < 2) {
                        wl_free(wltmp);
                        return (NORMAL_STR);
                    } else {
                        *num = nn - 1;
                        wl_free(wltmp);
                        return (BROKEN_STR);
                    }

                case CONTINUED: /* Continue. */
                    if (nn < 2) {
                        cn = NULL;
                        break;
                    } else {
                        *num = nn - 1;
                        wl_free(wltmp);
                        return (CONTINUED_STR);
                    }

                default:
                    cn = findlabel(i, bl->co_children);
                    if (!cn) {
                        wl_free(wltmp);
                        return (i);
                    }
                }
            }
        }
        wl_free(wltmp);
        break;

    case CO_BREAK:
        if (bl->co_numtimes > 0) {
            *num = bl->co_numtimes;
            return (BROKEN_STR);
        } else {
            fprintf(cp_err, "Warning: break %d a no-op\n",
                    bl->co_numtimes);
            return (NORMAL_STR);
        }

    case CO_CONTINUE:
        if (bl->co_numtimes > 0) {
            *num = bl->co_numtimes;
            return (CONTINUED_STR);
        } else {
            fprintf(cp_err, "Warning: continue %d a no-op\n",
                    bl->co_numtimes);
            return (NORMAL_STR);
        }

    case CO_GOTO:
        wl = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(bl->co_text))));
        wlword = wl->wl_word;
        wl->wl_word = NULL;
        wl_free(wl);
        return (wlword);

    case CO_LABEL:
        /* Do nothing. */
        cp_periodic();  /*CDHW needed to avoid lock-ups when loop contains only a label CDHW*/
        break;

    case CO_STATEMENT:
        docommand(wl_copy(bl->co_text));
        break;

    case CO_UNFILLED:
        /* There was probably an error here... */
        fprintf(cp_err, "Warning: ignoring previous error\n");
        break;

    default:
        fprintf(cp_err,
                "doblock: Internal Error: bad block type %d\n",
                bl->co_type);
        return (NORMAL_STR);
    }
    return (NORMAL_STR);
}
Beispiel #6
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();
}
Beispiel #7
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;
}