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

Defined functions

getnum defined in line 78; used 5 times
setCNL defined in line 293; used 6 times
setNAEOL defined in line 300; used 2 times
setcount defined in line 55; used 4 times
setdot1 defined in line 38; used 4 times
setnoaddr defined in line 111; used 16 times

Defined variables

bigmove defined in line 21; used 5 times
sccsid defined in line 2; never used
Last modified: 1981-07-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 987
Valid CSS Valid XHTML 1.0 Strict