# 2.11BSD#431 - /usr/src/ucb/ex/ex_addr.c

##### Functions

    address           X
    getnum            X
    setCNL            X
    setNAEOL          X
    setall            X
    setcount          X
    setdot            X
    setdot1           X
    setnoaddr         X

       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: #if !defined(lint) && defined(DOSCCS)
       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: }

#### Defined functions

address defined in line 134; used 4 times

- in /usr/src/ucb/ex/ex.h line 332
- in /usr/src/ucb/ex/ex_cmds.c line 94
- in /usr/src/ucb/ex/ex_cmdsub.c line 268
- in /usr/src/ucb/ex/ex_voper.c line 633

getnum defined in line 86; used 5 times

- in line 74, 154
- in /usr/src/ucb/ex/ex_set.c line 59, 102
- in /usr/src/ucb/ex/ex_v.c line 224

setCNL defined in line 301; used 6 times

- in /usr/src/ucb/ex/ex_cmds.c line 237, 254, 359, 445, 805, 844

setNAEOL defined in line 308; used 2 times

- in /usr/src/ucb/ex/ex_cmds.c line 569, 674

setall defined in line 99; used 5 times

- in /usr/src/ucb/ex/ex_cmds.c line 705-709(2), 813
- in /usr/src/ucb/ex/ex_io.c line 410
- in /usr/src/ucb/ex/ex_re.c line 43

setcount defined in line 63; used 4 times

- in line 304
- in /usr/src/ucb/ex/ex_cmds.c line 331, 729
- in /usr/src/ucb/ex/ex_re.c line 270

setdot defined in line 34; used 14 times

- in line 69-73(2)
- in /usr/src/ucb/ex/ex_cmds.c line 171, 312, 350, 416, 539, 758, 783, 825
- in /usr/src/ucb/ex/ex_cmdsub.c line 265, 767
- in /usr/src/ucb/ex/ex_io.c line 408
- in /usr/src/ucb/ex/ex_v.c line 150

setdot1 defined in line 46; used 4 times

- in line 37, 113
- in /usr/src/ucb/ex/ex_cmds.c line 66
- in /usr/src/ucb/ex/ex_cmdsub.c line 261

setnoaddr defined in line 119; used 16 times

- in line 311
- in /usr/src/ucb/ex/ex_cmds.c line 154, 161, 274, 292, 370, 391, 459, 486, 503, 562, 584, 646, 652, 661
- in /usr/src/ucb/ex/ex_set.c line 28

#### Defined variables

bigmove defined in line 29; used 5 times

- in line 38, 142, 150, 169, 281

sccsid defined in line 8; never used

Last modified: 1991-09-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1439 |