[BACK]Return to region.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/region.c, Revision 1.2

1.1       deraadt     1: /*
                      2:  *             Region based commands.
                      3:  * The routines in this file
                      4:  * deal with the region, that magic space
                      5:  * between "." and mark. Some functions are
                      6:  * commands. Some functions are just for
                      7:  * internal use.
                      8:  */
                      9: #include       "def.h"
                     10:
                     11: /*
                     12:  * Kill the region. Ask "getregion"
                     13:  * to figure out the bounds of the region.
                     14:  * Move "." to the start, and kill the characters.
                     15:  */
1.2     ! millert    16: /* ARGSUSED */
1.1       deraadt    17: killregion(f, n)
                     18: {
1.2     ! millert    19:        register int    s;
        !            20:        REGION          region;
1.1       deraadt    21:
1.2     ! millert    22:        if ((s = getregion(&region)) != TRUE)
1.1       deraadt    23:                return (s);
1.2     ! millert    24:        if ((lastflag & CFKILL) == 0)   /* This is a kill type   */
        !            25:                kdelete();      /* command, so do magic */
        !            26:        thisflag |= CFKILL;     /* kill buffer stuff.    */
1.1       deraadt    27:        curwp->w_dotp = region.r_linep;
                     28:        curwp->w_doto = region.r_offset;
                     29:        return (ldelete(region.r_size, KFORW));
                     30: }
                     31:
                     32: /*
                     33:  * Copy all of the characters in the
                     34:  * region to the kill buffer. Don't move dot
                     35:  * at all. This is a bit like a kill region followed
                     36:  * by a yank.
                     37:  */
1.2     ! millert    38: /* ARGSUSED */
1.1       deraadt    39: copyregion(f, n)
                     40: {
1.2     ! millert    41:        register LINE  *linep;
        !            42:        register int    loffs;
        !            43:        register int    s;
        !            44:        REGION          region;
        !            45:        VOID            kdelete();
1.1       deraadt    46:
1.2     ! millert    47:        if ((s = getregion(&region)) != TRUE)
1.1       deraadt    48:                return s;
1.2     ! millert    49:        if ((lastflag & CFKILL) == 0)   /* Kill type command.    */
1.1       deraadt    50:                kdelete();
                     51:        thisflag |= CFKILL;
1.2     ! millert    52:        linep = region.r_linep; /* Current line.         */
        !            53:        loffs = region.r_offset;/* Current offset.       */
1.1       deraadt    54:        while (region.r_size--) {
1.2     ! millert    55:                if (loffs == llength(linep)) {  /* End of line.          */
        !            56:                        if ((s = kinsert('\n', KFORW)) != TRUE)
1.1       deraadt    57:                                return (s);
                     58:                        linep = lforw(linep);
                     59:                        loffs = 0;
1.2     ! millert    60:                } else {        /* Middle of line.       */
        !            61:                        if ((s = kinsert(lgetc(linep, loffs), KFORW)) != TRUE)
1.1       deraadt    62:                                return s;
                     63:                        ++loffs;
                     64:                }
                     65:        }
                     66:        return TRUE;
                     67: }
                     68:
                     69: /*
                     70:  * Lower case region. Zap all of the upper
                     71:  * case characters in the region to lower case. Use
                     72:  * the region code to set the limits. Scan the buffer,
                     73:  * doing the changes. Call "lchange" to ensure that
                     74:  * redisplay is done in all buffers.
                     75:  */
1.2     ! millert    76: /* ARGSUSED */
1.1       deraadt    77: lowerregion(f, n)
                     78: {
1.2     ! millert    79:        register LINE  *linep;
        !            80:        register int    loffs;
        !            81:        register int    c;
        !            82:        register int    s;
        !            83:        REGION          region;
1.1       deraadt    84:
1.2     ! millert    85:        if ((s = getregion(&region)) != TRUE)
1.1       deraadt    86:                return s;
                     87:        lchange(WFHARD);
                     88:        linep = region.r_linep;
                     89:        loffs = region.r_offset;
                     90:        while (region.r_size--) {
                     91:                if (loffs == llength(linep)) {
                     92:                        linep = lforw(linep);
                     93:                        loffs = 0;
                     94:                } else {
                     95:                        c = lgetc(linep, loffs);
                     96:                        if (ISUPPER(c) != FALSE)
                     97:                                lputc(linep, loffs, TOLOWER(c));
                     98:                        ++loffs;
                     99:                }
                    100:        }
                    101:        return TRUE;
                    102: }
                    103:
                    104: /*
                    105:  * Upper case region. Zap all of the lower
                    106:  * case characters in the region to upper case. Use
                    107:  * the region code to set the limits. Scan the buffer,
                    108:  * doing the changes. Call "lchange" to ensure that
                    109:  * redisplay is done in all buffers.
                    110:  */
1.2     ! millert   111: /* ARGSUSED */
1.1       deraadt   112: upperregion(f, n)
                    113: {
1.2     ! millert   114:        register LINE  *linep;
        !           115:        register int    loffs;
        !           116:        register int    c;
        !           117:        register int    s;
        !           118:        REGION          region;
        !           119:        VOID            lchange();
1.1       deraadt   120:
1.2     ! millert   121:        if ((s = getregion(&region)) != TRUE)
1.1       deraadt   122:                return s;
                    123:        lchange(WFHARD);
                    124:        linep = region.r_linep;
                    125:        loffs = region.r_offset;
                    126:        while (region.r_size--) {
                    127:                if (loffs == llength(linep)) {
                    128:                        linep = lforw(linep);
                    129:                        loffs = 0;
                    130:                } else {
                    131:                        c = lgetc(linep, loffs);
                    132:                        if (ISLOWER(c) != FALSE)
                    133:                                lputc(linep, loffs, TOUPPER(c));
                    134:                        ++loffs;
                    135:                }
                    136:        }
                    137:        return TRUE;
                    138: }
                    139:
                    140: /*
                    141:  * This routine figures out the bound of the region
                    142:  * in the current window, and stores the results into the fields
                    143:  * of the REGION structure. Dot and mark are usually close together,
                    144:  * but I don't know the order, so I scan outward from dot, in both
                    145:  * directions, looking for mark. The size is kept in a long. At the
                    146:  * end, after the size is figured out, it is assigned to the size
                    147:  * field of the region structure. If this assignment loses any bits,
                    148:  * then we print an error. This is "type independent" overflow
                    149:  * checking. All of the callers of this routine should be ready to
                    150:  * get an ABORT status, because I might add a "if regions is big,
                    151:  * ask before clobberring" flag.
                    152:  */
1.2     ! millert   153: getregion(rp)
        !           154:        register REGION *rp;
        !           155: {
        !           156:        register LINE  *flp;
        !           157:        register LINE  *blp;
        !           158:        register long   fsize;  /* Long now.             */
        !           159:        register long   bsize;
1.1       deraadt   160:
                    161:        if (curwp->w_markp == NULL) {
                    162:                ewprintf("No mark set in this window");
                    163:                return (FALSE);
                    164:        }
1.2     ! millert   165:        if (curwp->w_dotp == curwp->w_markp) {  /* "r_size" always ok.   */
1.1       deraadt   166:                rp->r_linep = curwp->w_dotp;
                    167:                if (curwp->w_doto < curwp->w_marko) {
                    168:                        rp->r_offset = curwp->w_doto;
1.2     ! millert   169:                        rp->r_size = (RSIZE) (curwp->w_marko - curwp->w_doto);
1.1       deraadt   170:                } else {
                    171:                        rp->r_offset = curwp->w_marko;
1.2     ! millert   172:                        rp->r_size = (RSIZE) (curwp->w_doto - curwp->w_marko);
1.1       deraadt   173:                }
                    174:                return TRUE;
                    175:        }
1.2     ! millert   176:        flp = blp = curwp->w_dotp;      /* Get region size.      */
1.1       deraadt   177:        bsize = curwp->w_doto;
1.2     ! millert   178:        fsize = llength(flp) - curwp->w_doto + 1;
        !           179:        while (lforw(flp) != curbp->b_linep || lback(blp) != curbp->b_linep) {
1.1       deraadt   180:                if (lforw(flp) != curbp->b_linep) {
                    181:                        flp = lforw(flp);
                    182:                        if (flp == curwp->w_markp) {
                    183:                                rp->r_linep = curwp->w_dotp;
                    184:                                rp->r_offset = curwp->w_doto;
                    185:                                return (setsize(rp,
1.2     ! millert   186:                                         (RSIZE) (fsize + curwp->w_marko)));
1.1       deraadt   187:                        }
1.2     ! millert   188:                        fsize += llength(flp) + 1;
1.1       deraadt   189:                }
                    190:                if (lback(blp) != curbp->b_linep) {
                    191:                        blp = lback(blp);
1.2     ! millert   192:                        bsize += llength(blp) + 1;
1.1       deraadt   193:                        if (blp == curwp->w_markp) {
                    194:                                rp->r_linep = blp;
                    195:                                rp->r_offset = curwp->w_marko;
                    196:                                return (setsize(rp,
1.2     ! millert   197:                                         (RSIZE) (bsize - curwp->w_marko)));
1.1       deraadt   198:                        }
                    199:                }
                    200:        }
1.2     ! millert   201:        ewprintf("Bug: lost mark");     /* Gak!                  */
1.1       deraadt   202:        return FALSE;
                    203: }
                    204:
                    205: /*
                    206:  * Set size, and check for overflow.
                    207:  */
1.2     ! millert   208: setsize(rp, size)
        !           209:        register REGION *rp;
        !           210:        register RSIZE  size;
        !           211: {
1.1       deraadt   212:
                    213:        rp->r_size = size;
                    214:        if (rp->r_size != size) {
                    215:                ewprintf("Region is too large");
                    216:                return FALSE;
                    217:        }
                    218:        return TRUE;
                    219: }
                    220:
                    221: #ifdef PREFIXREGION
                    222: /*
                    223:  * Implements one of my favorite keyboard macros; put a string at the
                    224:  * beginning of a number of lines in a buffer. The quote string is
                    225:  * settable by using set-prefix-string.         Great for quoting mail, which
                    226:  * is the real reason I wrote it, but also has uses for creating bar
                    227:  * comments (like the one you're reading) in C code.
                    228:  */
                    229:
                    230: #define PREFIXLENGTH 40
1.2     ! millert   231: static char     prefix_string[PREFIXLENGTH] = {'>', '\0'};
1.1       deraadt   232:
                    233: /*
                    234:  * Prefix the region with whatever is in prefix_string.
                    235:  * Leaves dot at the beginning of the line after the end
                    236:  * of the region.  If an argument is given, prompts for the
                    237:  * line prefix string.
                    238:  */
                    239:
1.2     ! millert   240: /* ARGSUSED */
1.1       deraadt   241: prefixregion(f, n)
                    242: {
1.2     ! millert   243:        register int    s;
        !           244:        register LINE  *first, *last;
        !           245:        register int    nline;
        !           246:        REGION          region;
        !           247:        char           *prefix = prefix_string;
1.1       deraadt   248:
                    249:        if ((f == TRUE) && ((s = setprefix(FFRAND, 1)) != TRUE))
                    250:                return s;
                    251:
                    252:        /* get # of lines to affect */
                    253:        if ((s = getregion(&region)) != TRUE)
                    254:                return (s);
                    255:        first = region.r_linep;
                    256:        last = (first == curwp->w_dotp) ? curwp->w_markp : curwp->w_dotp;
                    257:        for (nline = 1; first != last; nline++)
                    258:                first = lforw(first);
                    259:
1.2     ! millert   260:        /* move to beginning of region */
1.1       deraadt   261:        curwp->w_dotp = region.r_linep;
                    262:        curwp->w_doto = region.r_offset;
                    263:
                    264:        /* for each line, go to beginning and insert the prefix string */
                    265:        while (nline--) {
                    266:                (VOID) gotobol(FFRAND, 1);
                    267:                for (prefix = prefix_string; *prefix; prefix++)
                    268:                        (VOID) linsert(1, *prefix);
                    269:                (VOID) forwline(FFRAND, 1);
                    270:        }
                    271:        (VOID) gotobol(FFRAND, 1);
                    272:        return TRUE;
                    273: }
                    274:
                    275: /*
                    276:  * Set prefix string.
                    277:  */
                    278:
1.2     ! millert   279: /* ARGSUSED */
1.1       deraadt   280: setprefix(f, n)
                    281: {
1.2     ! millert   282:        char            buf[PREFIXLENGTH];
        !           283:        register int    s;
1.1       deraadt   284:
                    285:        if (prefix_string[0] == '\0')
1.2     ! millert   286:                s = ereply("Prefix string: ", buf, sizeof buf);
1.1       deraadt   287:        else
                    288:                s = ereply("Prefix string (default %s): ",
1.2     ! millert   289:                           buf, sizeof buf, prefix_string);
1.1       deraadt   290:        if (s == TRUE)
                    291:                (VOID) strcpy(prefix_string, buf);
1.2     ! millert   292:        if ((s == FALSE) && (prefix_string[0] != '\0')) /* CR -- use old one */
1.1       deraadt   293:                s = TRUE;
                    294:        return s;
                    295: }
                    296: #endif