|
|
1.1 ! root 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.6 (Berkeley) 1/2/88"; ! 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, (line *) 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, (line *) 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: flusho(); ! 719: wdot = NOLINE; ! 720: } ! 721: ! 722: /* ! 723: * Find single character c, in direction dir from cursor. ! 724: */ ! 725: find(c) ! 726: char c; ! 727: { ! 728: ! 729: for(;;) { ! 730: if (edge()) ! 731: return (0); ! 732: wcursor += dir; ! 733: if (*wcursor == c) ! 734: return (1); ! 735: } ! 736: } ! 737: ! 738: /* ! 739: * Do a word motion with operator op, and cnt more words ! 740: * to go after this. ! 741: */ ! 742: word(op, cnt) ! 743: register int (*op)(); ! 744: int cnt; ! 745: { ! 746: register int which; ! 747: register char *iwc; ! 748: register line *iwdot = wdot; ! 749: ! 750: if (dir == 1) { ! 751: iwc = wcursor; ! 752: which = wordch(wcursor); ! 753: while (wordof(which, wcursor)) { ! 754: if (cnt == 1 && op != vmove && wcursor[1] == 0) { ! 755: wcursor++; ! 756: break; ! 757: } ! 758: if (!lnext()) ! 759: return (0); ! 760: if (wcursor == linebuf) ! 761: break; ! 762: } ! 763: /* Unless last segment of a change skip blanks */ ! 764: if (op != vchange || cnt > 1) ! 765: while (!margin() && blank()) ! 766: wcursor++; ! 767: else ! 768: if (wcursor == iwc && iwdot == wdot && *iwc) ! 769: wcursor++; ! 770: if (op == vmove && margin()) ! 771: wcursor--; ! 772: } else { ! 773: if (!lnext()) ! 774: return (0); ! 775: while (blank()) ! 776: if (!lnext()) ! 777: return (0); ! 778: if (!margin()) { ! 779: which = wordch(wcursor); ! 780: while (!margin() && wordof(which, wcursor)) ! 781: wcursor--; ! 782: } ! 783: if (wcursor < linebuf || !wordof(which, wcursor)) ! 784: wcursor++; ! 785: } ! 786: return (1); ! 787: } ! 788: ! 789: /* ! 790: * To end of word, with operator op and cnt more motions ! 791: * remaining after this. ! 792: */ ! 793: eend(op) ! 794: register int (*op)(); ! 795: { ! 796: register int which; ! 797: ! 798: if (!lnext()) ! 799: return; ! 800: while (blank()) ! 801: if (!lnext()) ! 802: return; ! 803: which = wordch(wcursor); ! 804: while (wordof(which, wcursor)) { ! 805: if (wcursor[1] == 0) { ! 806: wcursor++; ! 807: break; ! 808: } ! 809: if (!lnext()) ! 810: return; ! 811: } ! 812: if (op != vchange && op != vdelete && wcursor > linebuf) ! 813: wcursor--; ! 814: } ! 815: ! 816: /* ! 817: * Wordof tells whether the character at *wc is in a word of ! 818: * kind which (blank/nonblank words are 0, conservative words 1). ! 819: */ ! 820: wordof(which, wc) ! 821: char which; ! 822: register char *wc; ! 823: { ! 824: ! 825: if (isspace(*wc)) ! 826: return (0); ! 827: return (!wdkind || wordch(wc) == which); ! 828: } ! 829: ! 830: /* ! 831: * Wordch tells whether character at *wc is a word character ! 832: * i.e. an alfa, digit, or underscore. ! 833: */ ! 834: wordch(wc) ! 835: char *wc; ! 836: { ! 837: register int c; ! 838: ! 839: c = wc[0]; ! 840: return (isalpha(c) || isdigit(c) || c == '_'); ! 841: } ! 842: ! 843: /* ! 844: * Edge tells when we hit the last character in the current line. ! 845: */ ! 846: edge() ! 847: { ! 848: ! 849: if (linebuf[0] == 0) ! 850: return (1); ! 851: if (dir == 1) ! 852: return (wcursor[1] == 0); ! 853: else ! 854: return (wcursor == linebuf); ! 855: } ! 856: ! 857: /* ! 858: * Margin tells us when we have fallen off the end of the line. ! 859: */ ! 860: margin() ! 861: { ! 862: ! 863: return (wcursor < linebuf || wcursor[0] == 0); ! 864: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.