示例#1
0
static void
destroy_symbol(void *ptr)
{
    struct symbol *sym = (struct symbol *) ptr;
    if (! sym)
        return;
    switch (sym->type) {
        case UNKNOWN:
            break;
        case TERMINAL:
            destroy_terminal(&sym->t);
            break;
        case NONTERMINAL:
        case START_NONTERMINAL:
            destroy_nonterminal(&sym->nt);
            break;
    }
    if (sym->host_type)
        free((void *)sym->host_type);
    if (sym->destructor_code)
        free((void *)sym->destructor_code);
    free(sym);
}
示例#2
0
void destroy_all_terminals()
{
    struct terminal *term;
    while ((void *)(term = terminals.next) != &terminals) destroy_terminal(term);
}
示例#3
0
void in_term(struct terminal *term)
{
    struct event *ev;
    int r;
    unsigned char *iq;
    if ((unsigned)term->qlen + ALLOC_GR > MAXINT) overalloc();
    iq = mem_realloc(term->input_queue, term->qlen + ALLOC_GR);
    term->input_queue = iq;
    if ((r = read(term->fdin, iq + term->qlen, ALLOC_GR)) <= 0) {
        if (r == -1 && errno != ECONNRESET) error("ERROR: error %d on terminal: could not read event", errno);
        destroy_terminal(term);
        return;
    }
    term->qlen += r;
test_queue:
    if ((size_t)term->qlen < sizeof(struct event)) return;
    ev = (struct event *)iq;
    r = sizeof(struct event);
    if (ev->ev != EV_INIT && ev->ev != EV_RESIZE && ev->ev != EV_REDRAW && ev->ev != EV_KBD && ev->ev != EV_MOUSE && ev->ev != EV_ABORT) {
        error("ERROR: error on terminal: bad event %d", ev->ev);
        goto mm;
    }
    if (ev->ev == EV_INIT) {
        int init_len;
        if ((size_t)term->qlen < sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int)) return;
        init_len = *(int *)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + sizeof(int));
        if ((size_t)term->qlen < sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int) + init_len) return;
        memcpy(term->term, iq + sizeof(struct event), MAX_TERM_LEN);
        term->term[MAX_TERM_LEN - 1] = 0;
        memcpy(term->cwd, iq + sizeof(struct event) + MAX_TERM_LEN, MAX_CWD_LEN);
        term->cwd[MAX_CWD_LEN - 1] = 0;
        term->environment = *(int *)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN);
        ev->b = (long)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + sizeof(int));
        r = sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int) + init_len;
        sync_term_specs();
    }
    if (ev->ev == EV_REDRAW || ev->ev == EV_RESIZE || ev->ev == EV_INIT) {
        struct window *win;
send_redraw:
        if (ev->x < 0 || ev->y < 0) {
            error("ERROR: bad terminal size: %d, %d", (int)ev->x, (int)ev->y);
            goto mm;
        }
        alloc_term_screen(term, ev->x, ev->y);
        clear_terminal(term);
        erase_screen(term);
        term->redrawing = 1;
        foreachback(win, term->windows) win->handler(win, ev, 0);
        term->redrawing = 0;
    }
    if (ev->ev == EV_KBD || ev->ev == EV_MOUSE) {
        if (ev->ev == EV_KBD && upcase(ev->x) == 'L' && ev->y == KBD_CTRL) {
            ev->ev = EV_REDRAW;
            ev->x = term->x;
            ev->y = term->y;
            goto send_redraw;
        }
        else if (ev->ev == EV_KBD && ev->x == KBD_CTRL_C) ((struct window *)term->windows.prev)->handler(term->windows.prev, ev, 0);
        else ((struct window *)term->windows.next)->handler(term->windows.next, ev, 0);
    }
    if (ev->ev == EV_ABORT) {
        destroy_terminal(term);
        return;
    }
    /*redraw_screen(term);*/
mm:
    if (term->qlen == r) term->qlen = 0;
    else memmove(iq, iq + r, term->qlen -= r);
    goto test_queue;
}