Annotation of 43BSD/ucb/ex/ex_addr.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char *sccsid = "@(#)ex_addr.c   7.3 (Berkeley) 6/7/85";
        !             9: #endif not lint
        !            10: 
        !            11: #include "ex.h"
        !            12: #include "ex_re.h"
        !            13: 
        !            14: /*
        !            15:  * Routines for address parsing and assignment and checking of address bounds
        !            16:  * in command mode.  The routine address is called from ex_cmds.c
        !            17:  * to parse each component of a command (terminated by , ; or the beginning
        !            18:  * of the command itself.  It is also called by the scanning routine
        !            19:  * in ex_voperate.c from within open/visual.
        !            20:  *
        !            21:  * Other routines here manipulate the externals addr1 and addr2.
        !            22:  * These are the first and last lines for the current command.
        !            23:  *
        !            24:  * The variable bigmove remembers whether a non-local glitch of . was
        !            25:  * involved in an address expression, so we can set the previous context
        !            26:  * mark '' when such a motion occurs.
        !            27:  */
        !            28: 
        !            29: static bool bigmove;
        !            30: 
        !            31: /*
        !            32:  * Set up addr1 and addr2 for commands whose default address is dot.
        !            33:  */
        !            34: setdot()
        !            35: {
        !            36: 
        !            37:        setdot1();
        !            38:        if (bigmove)
        !            39:                markDOT();
        !            40: }
        !            41: 
        !            42: /*
        !            43:  * Call setdot1 to set up default addresses without ever
        !            44:  * setting the previous context mark.
        !            45:  */
        !            46: setdot1()
        !            47: {
        !            48: 
        !            49:        if (addr2 == 0)
        !            50:                addr1 = addr2 = dot;
        !            51:        if (addr1 > addr2) {
        !            52:                notempty();
        !            53:                error("Addr1 > addr2|First address exceeds second");
        !            54:        }
        !            55: }
        !            56: 
        !            57: /*
        !            58:  * Ex allows you to say
        !            59:  *     delete 5
        !            60:  * to delete 5 lines, etc.
        !            61:  * Such nonsense is implemented by setcount.
        !            62:  */
        !            63: setcount()
        !            64: {
        !            65:        register int cnt;
        !            66: 
        !            67:        pastwh();
        !            68:        if (!isdigit(peekchar())) {
        !            69:                setdot();
        !            70:                return;
        !            71:        }
        !            72:        addr1 = addr2;
        !            73:        setdot();
        !            74:        cnt = getnum();
        !            75:        if (cnt <= 0)
        !            76:                error("Bad count|Nonzero count required");
        !            77:        addr2 += cnt - 1;
        !            78:        if (addr2 > dol)
        !            79:                addr2 = dol;
        !            80:        nonzero();
        !            81: }
        !            82: 
        !            83: /*
        !            84:  * Parse a number out of the command input stream.
        !            85:  */
        !            86: getnum()
        !            87: {
        !            88:        register int cnt;
        !            89: 
        !            90:        for (cnt = 0; isdigit(peekcd());)
        !            91:                cnt = cnt * 10 + getchar() - '0';
        !            92:        return (cnt);
        !            93: }
        !            94: 
        !            95: /*
        !            96:  * Set the default addresses for commands which use the whole
        !            97:  * buffer as default, notably write.
        !            98:  */
        !            99: setall()
        !           100: {
        !           101: 
        !           102:        if (addr2 == 0) {
        !           103:                addr1 = one;
        !           104:                addr2 = dol;
        !           105:                if (dol == zero) {
        !           106:                        dot = zero;
        !           107:                        return;
        !           108:                }
        !           109:        }
        !           110:        /*
        !           111:         * Don't want to set previous context mark so use setdot1().
        !           112:         */
        !           113:        setdot1();
        !           114: }
        !           115: 
        !           116: /*
        !           117:  * No address allowed on, e.g. the file command.
        !           118:  */
        !           119: setnoaddr()
        !           120: {
        !           121: 
        !           122:        if (addr2 != 0)
        !           123:                error("No address allowed@on this command");
        !           124: }
        !           125: 
        !           126: /*
        !           127:  * Parse an address.
        !           128:  * Just about any sequence of address characters is legal.
        !           129:  *
        !           130:  * If you are tricky you can use this routine and the = command
        !           131:  * to do simple addition and subtraction of cardinals less
        !           132:  * than the number of lines in the file.
        !           133:  */
        !           134: line *
        !           135: address(inline)
        !           136:        char *inline;
        !           137: {
        !           138:        register line *addr;
        !           139:        register int offset, c;
        !           140:        short lastsign;
        !           141: 
        !           142:        bigmove = 0;
        !           143:        lastsign = 0;
        !           144:        offset = 0;
        !           145:        addr = 0;
        !           146:        for (;;) {
        !           147:                if (isdigit(peekcd())) {
        !           148:                        if (addr == 0) {
        !           149:                                addr = zero;
        !           150:                                bigmove = 1;
        !           151:                        }
        !           152:                        loc1 = 0;
        !           153:                        addr += offset;
        !           154:                        offset = getnum();
        !           155:                        if (lastsign >= 0)
        !           156:                                addr += offset;
        !           157:                        else
        !           158:                                addr -= offset;
        !           159:                        lastsign = 0;
        !           160:                        offset = 0;
        !           161:                }
        !           162:                switch (c = getcd()) {
        !           163: 
        !           164:                case '?':
        !           165:                case '/':
        !           166:                case '$':
        !           167:                case '\'':
        !           168:                case '\\':
        !           169:                        bigmove++;
        !           170:                case '.':
        !           171:                        if (addr || offset)
        !           172:                                error("Badly formed address");
        !           173:                }
        !           174:                offset += lastsign;
        !           175:                lastsign = 0;
        !           176:                switch (c) {
        !           177: 
        !           178:                case ' ':
        !           179:                case '\t':
        !           180:                        continue;
        !           181: 
        !           182:                case '+':
        !           183:                        lastsign = 1;
        !           184:                        if (addr == 0)
        !           185:                                addr = dot;
        !           186:                        continue;
        !           187: 
        !           188:                case '^':
        !           189:                case '-':
        !           190:                        lastsign = -1;
        !           191:                        if (addr == 0)
        !           192:                                addr = dot;
        !           193:                        continue;
        !           194: 
        !           195:                case '\\':
        !           196:                case '?':
        !           197:                case '/':
        !           198:                        c = compile(c, 1);
        !           199:                        notempty();
        !           200:                        savere(scanre);
        !           201:                        addr = dot;
        !           202:                        if (inline && execute(0, dot)) {
        !           203:                                if (c == '/') {
        !           204:                                        while (loc1 <= inline) {
        !           205:                                                if (loc1 == loc2)
        !           206:                                                        loc2++;
        !           207:                                                if (!execute(1))
        !           208:                                                        goto nope;
        !           209:                                        }
        !           210:                                        break;
        !           211:                                } else if (loc1 < inline) {
        !           212:                                        char *last;
        !           213: doques:
        !           214: 
        !           215:                                        do {
        !           216:                                                last = loc1;
        !           217:                                                if (loc1 == loc2)
        !           218:                                                        loc2++;
        !           219:                                                if (!execute(1))
        !           220:                                                        break;
        !           221:                                        } while (loc1 < inline);
        !           222:                                        loc1 = last;
        !           223:                                        break;
        !           224:                                }
        !           225:                        }
        !           226: nope:
        !           227:                        for (;;) {
        !           228:                                if (c == '/') {
        !           229:                                        addr++;
        !           230:                                        if (addr > dol) {
        !           231:                                                if (value(WRAPSCAN) == 0)
        !           232: error("No match to BOTTOM|Address search hit BOTTOM without matching pattern");
        !           233:                                                addr = zero;
        !           234:                                        }
        !           235:                                } else {
        !           236:                                        addr--;
        !           237:                                        if (addr < zero) {
        !           238:                                                if (value(WRAPSCAN) == 0)
        !           239: error("No match to TOP|Address search hit TOP without matching pattern");
        !           240:                                                addr = dol;
        !           241:                                        }
        !           242:                                }
        !           243:                                if (execute(0, addr)) {
        !           244:                                        if (inline && c == '?') {
        !           245:                                                inline = &linebuf[LBSIZE];
        !           246:                                                goto doques;
        !           247:                                        }
        !           248:                                        break;
        !           249:                                }
        !           250:                                if (addr == dot)
        !           251:                                        error("Fail|Pattern not found");
        !           252:                        }
        !           253:                        continue;
        !           254: 
        !           255:                case '$':
        !           256:                        addr = dol;
        !           257:                        continue;
        !           258: 
        !           259:                case '.':
        !           260:                        addr = dot;
        !           261:                        continue;
        !           262: 
        !           263:                case '\'':
        !           264:                        c = markreg(getchar());
        !           265:                        if (c == 0)
        !           266:                                error("Marks are ' and a-z");
        !           267:                        addr = getmark(c);
        !           268:                        if (addr == 0)
        !           269:                                error("Undefined mark@referenced");
        !           270:                        break;
        !           271: 
        !           272:                default:
        !           273:                        ungetchar(c);
        !           274:                        if (offset) {
        !           275:                                if (addr == 0)
        !           276:                                        addr = dot;
        !           277:                                addr += offset;
        !           278:                                loc1 = 0;
        !           279:                        }
        !           280:                        if (addr == 0) {
        !           281:                                bigmove = 0;
        !           282:                                return (0);
        !           283:                        }
        !           284:                        if (addr != zero)
        !           285:                                notempty();
        !           286:                        addr += lastsign;
        !           287:                        if (addr < zero)
        !           288:                                error("Negative address@- first buffer line is 1");
        !           289:                        if (addr > dol)
        !           290:                                error("Not that many lines@in buffer");
        !           291:                        return (addr);
        !           292:                }
        !           293:        }
        !           294: }
        !           295: 
        !           296: /*
        !           297:  * Abbreviations to make code smaller
        !           298:  * Left over from squashing ex version 1.1 into
        !           299:  * 11/34's and 11/40's.
        !           300:  */
        !           301: setCNL()
        !           302: {
        !           303: 
        !           304:        setcount();
        !           305:        newline();
        !           306: }
        !           307: 
        !           308: setNAEOL()
        !           309: {
        !           310: 
        !           311:        setnoaddr();
        !           312:        eol();
        !           313: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.