[BACK]Return to undo.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / bin / ed

Annotation of src/bin/ed/undo.c, Revision 1.5

1.5     ! msaitoh     1: /*     $NetBSD: undo.c,v 1.4 2005/02/17 16:29:26 xtraeme Exp $ */
1.2       cgd         2:
1.1       alm         3: /* undo.c: This file contains the undo routines for the ed line editor */
                      4: /*-
                      5:  * Copyright (c) 1993 Andrew Moore, Talke Studio.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
1.3       thorpej    30: #include <sys/cdefs.h>
1.1       alm        31: #ifndef lint
1.2       cgd        32: #if 0
1.1       alm        33: static char *rcsid = "@(#)undo.c,v 1.1 1994/02/01 00:34:44 alm Exp";
1.2       cgd        34: #else
1.5     ! msaitoh    35: __RCSID("$NetBSD: undo.c,v 1.4 2005/02/17 16:29:26 xtraeme Exp $");
1.2       cgd        36: #endif
1.1       alm        37: #endif /* not lint */
                     38:
                     39: #include "ed.h"
                     40:
                     41:
                     42: #define USIZE 100                              /* undo stack size */
                     43: undo_t *ustack = NULL;                         /* undo stack */
                     44: long usize = 0;                                        /* stack size variable */
                     45: long u_p = 0;                                  /* undo stack pointer */
                     46:
1.5     ! msaitoh    47: /* push_undo_stack: return pointer to initialized undo node */
1.1       alm        48: undo_t *
1.4       xtraeme    49: push_undo_stack(int type, long from, long to)
1.1       alm        50: {
                     51:        undo_t *t;
                     52:
                     53: #if defined(sun) || defined(NO_REALLOC_NULL)
                     54:        if (ustack == NULL &&
                     55:            (ustack = (undo_t *) malloc((usize = USIZE) * sizeof(undo_t))) == NULL) {
                     56:                fprintf(stderr, "%s\n", strerror(errno));
                     57:                sprintf(errmsg, "out of memory");
                     58:                return NULL;
                     59:        }
                     60: #endif
                     61:        t = ustack;
                     62:        if (u_p < usize ||
                     63:            (t = (undo_t *) realloc(ustack, (usize += USIZE) * sizeof(undo_t))) != NULL) {
                     64:                ustack = t;
                     65:                ustack[u_p].type = type;
                     66:                ustack[u_p].t = get_addressed_line_node(to);
                     67:                ustack[u_p].h = get_addressed_line_node(from);
                     68:                return ustack + u_p++;
                     69:        }
                     70:        /* out of memory - release undo stack */
                     71:        fprintf(stderr, "%s\n", strerror(errno));
                     72:        sprintf(errmsg, "out of memory");
                     73:        clear_undo_stack();
                     74:        free(ustack);
                     75:        ustack = NULL;
                     76:        usize = 0;
                     77:        return NULL;
                     78: }
                     79:
                     80:
                     81: /* USWAP: swap undo nodes */
                     82: #define USWAP(x,y) { \
                     83:        undo_t utmp; \
                     84:        utmp = x, x = y, y = utmp; \
                     85: }
                     86:
                     87:
                     88: long u_current_addr = -1;      /* if >= 0, undo enabled */
                     89: long u_addr_last = -1;         /* if >= 0, undo enabled */
                     90:
                     91: /* pop_undo_stack: undo last change to the editor buffer */
                     92: int
1.4       xtraeme    93: pop_undo_stack(void)
1.1       alm        94: {
                     95:        long n;
                     96:        long o_current_addr = current_addr;
                     97:        long o_addr_last = addr_last;
                     98:
                     99:        if (u_current_addr == -1 || u_addr_last == -1) {
                    100:                sprintf(errmsg, "nothing to undo");
                    101:                return ERR;
                    102:        } else if (u_p)
                    103:                modified = 1;
                    104:        get_addressed_line_node(0);     /* this get_addressed_line_node last! */
                    105:        SPL1();
                    106:        for (n = u_p; n-- > 0;) {
                    107:                switch(ustack[n].type) {
                    108:                case UADD:
                    109:                        REQUE(ustack[n].h->q_back, ustack[n].t->q_forw);
                    110:                        break;
                    111:                case UDEL:
                    112:                        REQUE(ustack[n].h->q_back, ustack[n].h);
                    113:                        REQUE(ustack[n].t, ustack[n].t->q_forw);
                    114:                        break;
                    115:                case UMOV:
                    116:                case VMOV:
                    117:                        REQUE(ustack[n - 1].h, ustack[n].h->q_forw);
                    118:                        REQUE(ustack[n].t->q_back, ustack[n - 1].t);
                    119:                        REQUE(ustack[n].h, ustack[n].t);
                    120:                        n--;
                    121:                        break;
                    122:                default:
                    123:                        /*NOTREACHED*/
                    124:                        ;
                    125:                }
                    126:                ustack[n].type ^= 1;
                    127:        }
                    128:        /* reverse undo stack order */
                    129:        for (n = u_p; n-- > (u_p + 1)/ 2;)
                    130:                USWAP(ustack[n], ustack[u_p - 1 - n]);
                    131:        if (isglobal)
                    132:                clear_active_list();
                    133:        current_addr = u_current_addr, u_current_addr = o_current_addr;
                    134:        addr_last = u_addr_last, u_addr_last = o_addr_last;
                    135:        SPL0();
                    136:        return 0;
                    137: }
                    138:
                    139:
                    140: /* clear_undo_stack: clear the undo stack */
                    141: void
1.4       xtraeme   142: clear_undo_stack(void)
1.1       alm       143: {
                    144:        line_t *lp, *ep, *tl;
                    145:
                    146:        while (u_p--)
                    147:                if (ustack[u_p].type == UDEL) {
                    148:                        ep = ustack[u_p].t->q_forw;
                    149:                        for (lp = ustack[u_p].h; lp != ep; lp = tl) {
                    150:                                unmark_line_node(lp);
                    151:                                tl = lp->q_forw;
                    152:                                free(lp);
                    153:                        }
                    154:                }
                    155:        u_p = 0;
                    156:        u_current_addr = current_addr;
                    157:        u_addr_last = addr_last;
                    158: }

CVSweb <webmaster@jp.NetBSD.org>