Exemplo n.º 1
0
/* Return NULL if no alias was found. We can get away with just
 * calling cp_histsubst now because the line will have gone onto the
 * history list by now and cp_histsubst will look in the right place.  */
static wordlist *
asubst(wordlist *wlist)
{
    struct alias *al;
    wordlist *wl;
    char *word;

    word = wlist->wl_word;
    if (*word == '\\') {
        while ((word[0] = word[1]) != '\0')
            word++;
        return (NULL);
    }

    for (al = cp_aliases; al; al = al->al_next)
        if (eq(word, al->al_name))
            break;
    if (!al)
        return (NULL);

    wl = cp_histsubst(wl_copy(al->al_text));

    if (cp_didhsubst) {
        /* Make sure that we have an up-to-date last history entry. */
        wl_free(cp_lastone->hi_wlist);
        cp_lastone->hi_wlist = wl_copy(wl);
    } else {
        /* If it had no history args, then append the rest of the wl */
        wl_append(wl, wl_copy(wlist->wl_next));
    }

    return (wl);
}
Exemplo n.º 2
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;
}
Exemplo n.º 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);
}
Exemplo n.º 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);
}
Exemplo n.º 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);
}