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

Defined functions

edge defined in line 845; used 2 times
eend defined in line 792; used 1 times
find defined in line 724; used 1 times
margin defined in line 859; used 9 times
operate defined in line 30; used 3 times
word defined in line 741; used 1 times
wordch defined in line 833; used 8 times
wordof defined in line 819; used 6 times

Defined variables

sccsid defined in line 8; never used
vscandir defined in line 18; used 3 times

Defined macros

blank defined in line 15; used 3 times
forbid defined in line 16; used 19 times
Last modified: 1985-06-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2084
Valid CSS Valid XHTML 1.0 Strict