Annotation of 3BSD/cmd/ex/ex_addr.c, revision 1.1

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

unix.superglobalmegacorp.com

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