1: /* Copyright (c) 1981 Regents of the University of California */
   2: static char *sccsid = "@(#)ex_voper.c	7.1	7/8/81";
   3: #include "ex.h"
   4: #include "ex_tty.h"
   5: #include "ex_vis.h"
   6: 
   7: #define blank()     isspace(wcursor[0])
   8: #define forbid(a)   if (a) goto errlab;
   9: 
  10: char    vscandir[2] =   { '/', 0 };
  11: 
  12: /*
  13:  * Decode an operator/operand type command.
  14:  * Eventually we switch to an operator subroutine in ex_vops.c.
  15:  * The work here is setting up a function variable to point
  16:  * to the routine we want, and manipulation of the variables
  17:  * wcursor and wdot, which mark the other end of the affected
  18:  * area.  If wdot is zero, then the current line is the other end,
  19:  * and if wcursor is zero, then the first non-blank location of the
  20:  * other line is implied.
  21:  */
  22: operate(c, cnt)
  23:     register int c, cnt;
  24: {
  25:     register int i;
  26:     int (*moveop)(), (*deleteop)();
  27:     register int (*opf)();
  28:     bool subop = 0;
  29:     char *oglobp, *ocurs;
  30:     register line *addr;
  31:     line *odot;
  32:     static char lastFKND, lastFCHR;
  33:     char d;
  34: 
  35:     moveop = vmove, deleteop = vdelete;
  36:     wcursor = cursor;
  37:     wdot = NOLINE;
  38:     notecnt = 0;
  39:     dir = 1;
  40:     switch (c) {
  41: 
  42:     /*
  43: 	 * d		delete operator.
  44: 	 */
  45:     case 'd':
  46:         moveop = vdelete;
  47:         deleteop = beep;
  48:         break;
  49: 
  50:     /*
  51: 	 * s		substitute characters, like c\040, i.e. change space.
  52: 	 */
  53:     case 's':
  54:         ungetkey(' ');
  55:         subop++;
  56:         /* fall into ... */
  57: 
  58:     /*
  59: 	 * c		Change operator.
  60: 	 */
  61:     case 'c':
  62:         if (c == 'c' && workcmd[0] == 'C' || workcmd[0] == 'S')
  63:             subop++;
  64:         moveop = vchange;
  65:         deleteop = beep;
  66:         break;
  67: 
  68:     /*
  69: 	 * !		Filter through a UNIX command.
  70: 	 */
  71:     case '!':
  72:         moveop = vfilter;
  73:         deleteop = beep;
  74:         break;
  75: 
  76:     /*
  77: 	 * y		Yank operator.  Place specified text so that it
  78: 	 *		can be put back with p/P.  Also yanks to named buffers.
  79: 	 */
  80:     case 'y':
  81:         moveop = vyankit;
  82:         deleteop = beep;
  83:         break;
  84: 
  85:     /*
  86: 	 * =		Reformat operator (for LISP).
  87: 	 */
  88: #ifdef LISPCODE
  89:     case '=':
  90:         forbid(!value(LISP));
  91:         /* fall into ... */
  92: #endif
  93: 
  94:     /*
  95: 	 * >		Right shift operator.
  96: 	 * <		Left shift operator.
  97: 	 */
  98:     case '<':
  99:     case '>':
 100:         moveop = vshftop;
 101:         deleteop = beep;
 102:         break;
 103: 
 104:     /*
 105: 	 * r		Replace character under cursor with single following
 106: 	 *		character.
 107: 	 */
 108:     case 'r':
 109:         vmacchng(1);
 110:         vrep(cnt);
 111:         return;
 112: 
 113:     default:
 114:         goto nocount;
 115:     }
 116:     vmacchng(1);
 117:     /*
 118: 	 * Had an operator, so accept another count.
 119: 	 * Multiply counts together.
 120: 	 */
 121:     if (isdigit(peekkey()) && peekkey() != '0') {
 122:         cnt *= vgetcnt();
 123:         Xcnt = cnt;
 124:         forbid (cnt <= 0);
 125:     }
 126: 
 127:     /*
 128: 	 * Get next character, mapping it and saving as
 129: 	 * part of command for repeat.
 130: 	 */
 131:     c = map(getesc(),arrows);
 132:     if (c == 0)
 133:         return;
 134:     if (!subop)
 135:         *lastcp++ = c;
 136: nocount:
 137:     opf = moveop;
 138:     switch (c) {
 139: 
 140:     /*
 141: 	 * b		Back up a word.
 142: 	 * B		Back up a word, liberal definition.
 143: 	 */
 144:     case 'b':
 145:     case 'B':
 146:         dir = -1;
 147:         /* fall into ... */
 148: 
 149:     /*
 150: 	 * w		Forward a word.
 151: 	 * W		Forward a word, liberal definition.
 152: 	 */
 153:     case 'W':
 154:     case 'w':
 155:         wdkind = c & ' ';
 156:         forbid(lfind(2, cnt, opf, 0) < 0);
 157:         vmoving = 0;
 158:         break;
 159: 
 160:     /*
 161: 	 * E		to end of following blank/nonblank word
 162: 	 */
 163:     case 'E':
 164:         wdkind = 0;
 165:         goto ein;
 166: 
 167:     /*
 168: 	 * e		To end of following word.
 169: 	 */
 170:     case 'e':
 171:         wdkind = 1;
 172: ein:
 173:         forbid(lfind(3, cnt - 1, opf, 0) < 0);
 174:         vmoving = 0;
 175:         break;
 176: 
 177:     /*
 178: 	 * (		Back an s-expression.
 179: 	 */
 180:     case '(':
 181:         dir = -1;
 182:         /* fall into... */
 183: 
 184:     /*
 185: 	 * )		Forward an s-expression.
 186: 	 */
 187:     case ')':
 188:         forbid(lfind(0, cnt, opf, (line *) 0) < 0);
 189:         markDOT();
 190:         break;
 191: 
 192:     /*
 193: 	 * {		Back an s-expression, but don't stop on atoms.
 194: 	 *		In text mode, a paragraph.  For C, a balanced set
 195: 	 *		of {}'s.
 196: 	 */
 197:     case '{':
 198:         dir = -1;
 199:         /* fall into... */
 200: 
 201:     /*
 202: 	 * }		Forward an s-expression, but don't stop on atoms.
 203: 	 *		In text mode, back paragraph.  For C, back a balanced
 204: 	 *		set of {}'s.
 205: 	 */
 206:     case '}':
 207:         forbid(lfind(1, cnt, opf, (line *) 0) < 0);
 208:         markDOT();
 209:         break;
 210: 
 211:     /*
 212: 	 * %		To matching () or {}.  If not at ( or { scan for
 213: 	 *		first such after cursor on this line.
 214: 	 */
 215:     case '%':
 216:         vsave();
 217:         i = lmatchp((line *) 0);
 218: #ifdef TRACE
 219:         if (trace)
 220:             fprintf(trace, "after lmatchp in %, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol));
 221: #endif
 222:         getDOT();
 223:         forbid(!i);
 224:         if (opf != vmove)
 225:             if (dir > 0)
 226:                 wcursor++;
 227:             else
 228:                 cursor++;
 229:         else
 230:             markDOT();
 231:         vmoving = 0;
 232:         break;
 233: 
 234:     /*
 235: 	 * [		Back to beginning of defun, i.e. an ( in column 1.
 236: 	 *		For text, back to a section macro.
 237: 	 *		For C, back to a { in column 1 (~~ beg of function.)
 238: 	 */
 239:     case '[':
 240:         dir = -1;
 241:         /* fall into ... */
 242: 
 243:     /*
 244: 	 * ]		Forward to next defun, i.e. a ( in column 1.
 245: 	 *		For text, forward section.
 246: 	 *		For C, forward to a } in column 1 (if delete or such)
 247: 	 *		or if a move to a { in column 1.
 248: 	 */
 249:     case ']':
 250:         if (!vglobp)
 251:             forbid(getkey() != c);
 252:         forbid (Xhadcnt);
 253:         vsave();
 254:         i = lbrack(c, opf);
 255:         getDOT();
 256:         forbid(!i);
 257:         markDOT();
 258:         if (ospeed > B300)
 259:             hold |= HOLDWIG;
 260:         break;
 261: 
 262:     /*
 263: 	 * ,		Invert last find with f F t or T, like inverse
 264: 	 *		of ;.
 265: 	 */
 266:     case ',':
 267:         forbid (lastFKND == 0);
 268:         c = isupper(lastFKND) ? tolower(lastFKND) : toupper(lastFKND);
 269:         i = lastFCHR;
 270:         if (vglobp == 0)
 271:             vglobp = "";
 272:         subop++;
 273:         goto nocount;
 274: 
 275:     /*
 276: 	 * 0		To beginning of real line.
 277: 	 */
 278:     case '0':
 279:         wcursor = linebuf;
 280:         vmoving = 0;
 281:         break;
 282: 
 283:     /*
 284: 	 * ;		Repeat last find with f F t or T.
 285: 	 */
 286:     case ';':
 287:         forbid (lastFKND == 0);
 288:         c = lastFKND;
 289:         i = lastFCHR;
 290:         subop++;
 291:         goto nocount;
 292: 
 293:     /*
 294: 	 * F		Find single character before cursor in current line.
 295: 	 * T		Like F, but stops before character.
 296: 	 */
 297:     case 'F':   /* inverted find */
 298:     case 'T':
 299:         dir = -1;
 300:         /* fall into ... */
 301: 
 302:     /*
 303: 	 * f		Find single character following cursor in current line.
 304: 	 * t		Like f, but stope before character.
 305: 	 */
 306:     case 'f':   /* find */
 307:     case 't':
 308:         if (!subop) {
 309:             i = getesc();
 310:             if (i == 0)
 311:                 return;
 312:             *lastcp++ = i;
 313:         }
 314:         if (vglobp == 0)
 315:             lastFKND = c, lastFCHR = i;
 316:         for (; cnt > 0; cnt--)
 317:             forbid (find(i) == 0);
 318:         vmoving = 0;
 319:         switch (c) {
 320: 
 321:         case 'T':
 322:             wcursor++;
 323:             break;
 324: 
 325:         case 't':
 326:             wcursor--;
 327:         case 'f':
 328: fixup:
 329:             if (moveop != vmove)
 330:                 wcursor++;
 331:             break;
 332:         }
 333:         break;
 334: 
 335:     /*
 336: 	 * |		Find specified print column in current line.
 337: 	 */
 338:     case '|':
 339:         if (Pline == numbline)
 340:             cnt += 8;
 341:         vmovcol = cnt;
 342:         vmoving = 1;
 343:         wcursor = vfindcol(cnt);
 344:         break;
 345: 
 346:     /*
 347: 	 * ^		To beginning of non-white space on line.
 348: 	 */
 349:     case '^':
 350:         wcursor = vskipwh(linebuf);
 351:         vmoving = 0;
 352:         break;
 353: 
 354:     /*
 355: 	 * $		To end of line.
 356: 	 */
 357:     case '$':
 358:         if (opf == vmove) {
 359:             vmoving = 1;
 360:             vmovcol = 20000;
 361:         } else
 362:             vmoving = 0;
 363:         if (cnt > 1) {
 364:             if (opf == vmove) {
 365:                 wcursor = 0;
 366:                 cnt--;
 367:             } else
 368:                 wcursor = linebuf;
 369:             /* This is wrong at EOF */
 370:             wdot = dot + cnt;
 371:             break;
 372:         }
 373:         if (linebuf[0]) {
 374:             wcursor = strend(linebuf) - 1;
 375:             goto fixup;
 376:         }
 377:         wcursor = linebuf;
 378:         break;
 379: 
 380:     /*
 381: 	 * h		Back a character.
 382: 	 * ^H		Back a character.
 383: 	 */
 384:     case 'h':
 385:     case CTRL(h):
 386:         dir = -1;
 387:         /* fall into ... */
 388: 
 389:     /*
 390: 	 * space	Forward a character.
 391: 	 */
 392:     case 'l':
 393:     case ' ':
 394:         forbid (margin() || opf == vmove && edge());
 395:         while (cnt > 0 && !margin())
 396:             wcursor += dir, cnt--;
 397:         if (margin() && opf == vmove || wcursor < linebuf)
 398:             wcursor -= dir;
 399:         vmoving = 0;
 400:         break;
 401: 
 402:     /*
 403: 	 * D		Delete to end of line, short for d$.
 404: 	 */
 405:     case 'D':
 406:         cnt = INF;
 407:         goto deleteit;
 408: 
 409:     /*
 410: 	 * X		Delete character before cursor.
 411: 	 */
 412:     case 'X':
 413:         dir = -1;
 414:         /* fall into ... */
 415: deleteit:
 416:     /*
 417: 	 * x		Delete character at cursor, leaving cursor where it is.
 418: 	 */
 419:     case 'x':
 420:         if (margin())
 421:             goto errlab;
 422:         vmacchng(1);
 423:         while (cnt > 0 && !margin())
 424:             wcursor += dir, cnt--;
 425:         opf = deleteop;
 426:         vmoving = 0;
 427:         break;
 428: 
 429:     default:
 430:         /*
 431: 		 * Stuttered operators are equivalent to the operator on
 432: 		 * a line, thus turn dd into d_.
 433: 		 */
 434:         if (opf == vmove || c != workcmd[0]) {
 435: errlab:
 436:             beep();
 437:             vmacp = 0;
 438:             return;
 439:         }
 440:         /* fall into ... */
 441: 
 442:     /*
 443: 	 * _		Target for a line or group of lines.
 444: 	 *		Stuttering is more convenient; this is mostly
 445: 	 *		for aesthetics.
 446: 	 */
 447:     case '_':
 448:         wdot = dot + cnt - 1;
 449:         vmoving = 0;
 450:         wcursor = 0;
 451:         break;
 452: 
 453:     /*
 454: 	 * H		To first, home line on screen.
 455: 	 *		Count is for count'th line rather than first.
 456: 	 */
 457:     case 'H':
 458:         wdot = (dot - vcline) + cnt - 1;
 459:         if (opf == vmove)
 460:             markit(wdot);
 461:         vmoving = 0;
 462:         wcursor = 0;
 463:         break;
 464: 
 465:     /*
 466: 	 * -		Backwards lines, to first non-white character.
 467: 	 */
 468:     case '-':
 469:         wdot = dot - cnt;
 470:         vmoving = 0;
 471:         wcursor = 0;
 472:         break;
 473: 
 474:     /*
 475: 	 * ^P		To previous line same column.  Ridiculous on the
 476: 	 *		console of the VAX since it puts console in LSI mode.
 477: 	 */
 478:     case 'k':
 479:     case CTRL(p):
 480:         wdot = dot - cnt;
 481:         if (vmoving == 0)
 482:             vmoving = 1, vmovcol = column(cursor);
 483:         wcursor = 0;
 484:         break;
 485: 
 486:     /*
 487: 	 * L		To last line on screen, or count'th line from the
 488: 	 *		bottom.
 489: 	 */
 490:     case 'L':
 491:         wdot = dot + vcnt - vcline - cnt;
 492:         if (opf == vmove)
 493:             markit(wdot);
 494:         vmoving = 0;
 495:         wcursor = 0;
 496:         break;
 497: 
 498:     /*
 499: 	 * M		To the middle of the screen.
 500: 	 */
 501:     case 'M':
 502:         wdot = dot + ((vcnt + 1) / 2) - vcline - 1;
 503:         if (opf == vmove)
 504:             markit(wdot);
 505:         vmoving = 0;
 506:         wcursor = 0;
 507:         break;
 508: 
 509:     /*
 510: 	 * +		Forward line, to first non-white.
 511: 	 *
 512: 	 * CR		Convenient synonym for +.
 513: 	 */
 514:     case '+':
 515:     case CR:
 516:         wdot = dot + cnt;
 517:         vmoving = 0;
 518:         wcursor = 0;
 519:         break;
 520: 
 521:     /*
 522: 	 * ^N		To next line, same column if possible.
 523: 	 *
 524: 	 * LF		Linefeed is a convenient synonym for ^N.
 525: 	 */
 526:     case CTRL(n):
 527:     case 'j':
 528:     case NL:
 529:         wdot = dot + cnt;
 530:         if (vmoving == 0)
 531:             vmoving = 1, vmovcol = column(cursor);
 532:         wcursor = 0;
 533:         break;
 534: 
 535:     /*
 536: 	 * n		Search to next match of current pattern.
 537: 	 */
 538:     case 'n':
 539:         vglobp = vscandir;
 540:         c = *vglobp++;
 541:         goto nocount;
 542: 
 543:     /*
 544: 	 * N		Like n but in reverse direction.
 545: 	 */
 546:     case 'N':
 547:         vglobp = vscandir[0] == '/' ? "?" : "/";
 548:         c = *vglobp++;
 549:         goto nocount;
 550: 
 551:     /*
 552: 	 * '		Return to line specified by following mark,
 553: 	 *		first white position on line.
 554: 	 *
 555: 	 * `		Return to marked line at remembered column.
 556: 	 */
 557:     case '\'':
 558:     case '`':
 559:         d = c;
 560:         c = getesc();
 561:         if (c == 0)
 562:             return;
 563:         c = markreg(c);
 564:         forbid (c == 0);
 565:         wdot = getmark(c);
 566:         forbid (wdot == NOLINE);
 567:         forbid (Xhadcnt);
 568:         vmoving = 0;
 569:         wcursor = d == '`' ? ncols[c - 'a'] : 0;
 570:         if (opf == vmove && (wdot != dot || (d == '`' && wcursor != cursor)))
 571:             markDOT();
 572:         if (wcursor) {
 573:             vsave();
 574:             getline(*wdot);
 575:             if (wcursor > strend(linebuf))
 576:                 wcursor = 0;
 577:             getDOT();
 578:         }
 579:         if (ospeed > B300)
 580:             hold |= HOLDWIG;
 581:         break;
 582: 
 583:     /*
 584: 	 * G		Goto count'th line, or last line if no count
 585: 	 *		given.
 586: 	 */
 587:     case 'G':
 588:         if (!Xhadcnt)
 589:             cnt = lineDOL();
 590:         wdot = zero + cnt;
 591:         forbid (wdot < one || wdot > dol);
 592:         if (opf == vmove)
 593:             markit(wdot);
 594:         vmoving = 0;
 595:         wcursor = 0;
 596:         break;
 597: 
 598:     /*
 599: 	 * /		Scan forward for following re.
 600: 	 * ?		Scan backward for following re.
 601: 	 */
 602:     case '/':
 603:     case '?':
 604:         forbid (Xhadcnt);
 605:         vsave();
 606:         ocurs = cursor;
 607:         odot = dot;
 608:         wcursor = 0;
 609:         if (readecho(c))
 610:             return;
 611:         if (!vglobp)
 612:             vscandir[0] = genbuf[0];
 613:         oglobp = globp; CP(vutmp, genbuf); globp = vutmp;
 614:         d = peekc;
 615: fromsemi:
 616:         ungetchar(0);
 617:         fixech();
 618:         CATCH
 619: #ifndef CBREAK
 620:             /*
 621: 			 * Lose typeahead (ick).
 622: 			 */
 623:             vcook();
 624: #endif
 625:             addr = address(cursor);
 626: #ifndef CBREAK
 627:             vraw();
 628: #endif
 629:         ONERR
 630: #ifndef CBREAK
 631:             vraw();
 632: #endif
 633: slerr:
 634:             globp = oglobp;
 635:             dot = odot;
 636:             cursor = ocurs;
 637:             ungetchar(d);
 638:             splitw = 0;
 639:             vclean();
 640:             vjumpto(dot, ocurs, 0);
 641:             return;
 642:         ENDCATCH
 643:         if (globp == 0)
 644:             globp = "";
 645:         else if (peekc)
 646:             --globp;
 647:         if (*globp == ';') {
 648:             /* /foo/;/bar/ */
 649:             globp++;
 650:             dot = addr;
 651:             cursor = loc1;
 652:             goto fromsemi;
 653:         }
 654:         dot = odot;
 655:         ungetchar(d);
 656:         c = 0;
 657:         if (*globp == 'z')
 658:             globp++, c = '\n';
 659:         if (any(*globp, "^+-."))
 660:             c = *globp++;
 661:         i = 0;
 662:         while (isdigit(*globp))
 663:             i = i * 10 + *globp++ - '0';
 664:         if (any(*globp, "^+-."))
 665:             c = *globp++;
 666:         if (*globp) {
 667:             /* random junk after the pattern */
 668:             beep();
 669:             goto slerr;
 670:         }
 671:         globp = oglobp;
 672:         splitw = 0;
 673:         vmoving = 0;
 674:         wcursor = loc1;
 675:         if (i != 0)
 676:             vsetsiz(i);
 677:         if (opf == vmove) {
 678:             if (state == ONEOPEN || state == HARDOPEN)
 679:                 outline = destline = WBOT;
 680:             if (addr != dot || loc1 != cursor)
 681:                 markDOT();
 682:             if (loc1 > linebuf && *loc1 == 0)
 683:                 loc1--;
 684:             if (c)
 685:                 vjumpto(addr, loc1, c);
 686:             else {
 687:                 vmoving = 0;
 688:                 if (loc1) {
 689:                     vmoving++;
 690:                     vmovcol = column(loc1);
 691:                 }
 692:                 getDOT();
 693:                 if (state == CRTOPEN && addr != dot)
 694:                     vup1();
 695:                 vupdown(addr - dot, NOSTR);
 696:             }
 697:             return;
 698:         }
 699:         lastcp[-1] = 'n';
 700:         getDOT();
 701:         wdot = addr;
 702:         break;
 703:     }
 704:     /*
 705: 	 * Apply.
 706: 	 */
 707:     if (vreg && wdot == 0)
 708:         wdot = dot;
 709:     (*opf)(c);
 710:     wdot = NOLINE;
 711: }
 712: 
 713: /*
 714:  * Find single character c, in direction dir from cursor.
 715:  */
 716: find(c)
 717:     char c;
 718: {
 719: 
 720:     for(;;) {
 721:         if (edge())
 722:             return (0);
 723:         wcursor += dir;
 724:         if (*wcursor == c)
 725:             return (1);
 726:     }
 727: }
 728: 
 729: /*
 730:  * Do a word motion with operator op, and cnt more words
 731:  * to go after this.
 732:  */
 733: word(op, cnt)
 734:     register int (*op)();
 735:     int cnt;
 736: {
 737:     register int which;
 738:     register char *iwc;
 739:     register line *iwdot = wdot;
 740: 
 741:     if (dir == 1) {
 742:         iwc = wcursor;
 743:         which = wordch(wcursor);
 744:         while (wordof(which, wcursor)) {
 745:             if (cnt == 1 && op != vmove && wcursor[1] == 0) {
 746:                 wcursor++;
 747:                 break;
 748:             }
 749:             if (!lnext())
 750:                 return (0);
 751:             if (wcursor == linebuf)
 752:                 break;
 753:         }
 754:         /* Unless last segment of a change skip blanks */
 755:         if (op != vchange || cnt > 1)
 756:             while (!margin() && blank())
 757:                 wcursor++;
 758:         else
 759:             if (wcursor == iwc && iwdot == wdot && *iwc)
 760:                 wcursor++;
 761:         if (op == vmove && margin())
 762:             wcursor--;
 763:     } else {
 764:         if (!lnext())
 765:             return (0);
 766:         while (blank())
 767:             if (!lnext())
 768:                 return (0);
 769:         if (!margin()) {
 770:             which = wordch(wcursor);
 771:             while (!margin() && wordof(which, wcursor))
 772:                 wcursor--;
 773:         }
 774:         if (wcursor < linebuf || !wordof(which, wcursor))
 775:             wcursor++;
 776:     }
 777:     return (1);
 778: }
 779: 
 780: /*
 781:  * To end of word, with operator op and cnt more motions
 782:  * remaining after this.
 783:  */
 784: eend(op)
 785:     register int (*op)();
 786: {
 787:     register int which;
 788: 
 789:     if (!lnext())
 790:         return;
 791:     while (blank())
 792:         if (!lnext())
 793:             return;
 794:     which = wordch(wcursor);
 795:     while (wordof(which, wcursor)) {
 796:         if (wcursor[1] == 0) {
 797:             wcursor++;
 798:             break;
 799:         }
 800:         if (!lnext())
 801:             return;
 802:     }
 803:     if (op != vchange && op != vdelete && wcursor > linebuf)
 804:         wcursor--;
 805: }
 806: 
 807: /*
 808:  * Wordof tells whether the character at *wc is in a word of
 809:  * kind which (blank/nonblank words are 0, conservative words 1).
 810:  */
 811: wordof(which, wc)
 812:     char which;
 813:     register char *wc;
 814: {
 815: 
 816:     if (isspace(*wc))
 817:         return (0);
 818:     return (!wdkind || wordch(wc) == which);
 819: }
 820: 
 821: /*
 822:  * Wordch tells whether character at *wc is a word character
 823:  * i.e. an alfa, digit, or underscore.
 824:  */
 825: wordch(wc)
 826:     char *wc;
 827: {
 828:     register int c;
 829: 
 830:     c = wc[0];
 831:     return (isalpha(c) || isdigit(c) || c == '_');
 832: }
 833: 
 834: /*
 835:  * Edge tells when we hit the last character in the current line.
 836:  */
 837: edge()
 838: {
 839: 
 840:     if (linebuf[0] == 0)
 841:         return (1);
 842:     if (dir == 1)
 843:         return (wcursor[1] == 0);
 844:     else
 845:         return (wcursor == linebuf);
 846: }
 847: 
 848: /*
 849:  * Margin tells us when we have fallen off the end of the line.
 850:  */
 851: margin()
 852: {
 853: 
 854:     return (wcursor < linebuf || wcursor[0] == 0);
 855: }

Defined functions

edge defined in line 837; used 2 times
eend defined in line 784; used 1 times
find defined in line 716; used 1 times
margin defined in line 851; used 9 times
operate defined in line 22; used 3 times
word defined in line 733; used 1 times
wordch defined in line 825; used 8 times
wordof defined in line 811; used 6 times

Defined variables

sccsid defined in line 2; never used
vscandir defined in line 10; used 3 times

Defined macros

blank defined in line 7; used 3 times
forbid defined in line 8; used 19 times
Last modified: 1981-07-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1491
Valid CSS Valid XHTML 1.0 Strict