Print this page
5088 it's probably ok for vi to stop working around pdp-11 bugs now
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/vi/port/ex_subr.c
+++ new/usr/src/cmd/vi/port/ex_subr.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 27 /* All Rights Reserved */
28 28
29 29
30 30 /* Copyright (c) 1981 Regents of the University of California */
31 31
32 32 #include <sys/stropts.h>
33 33 #include <sys/eucioctl.h>
34 34 #ifndef PRESUNEUC
35 35 #include <locale.h>
36 36 /* Undef putchar/getchar if they're defined. */
37 37 #ifdef putchar
38 38 # undef putchar
39 39 #endif
40 40 #ifdef getchar
41 41 # undef getchar
42 42 #endif
43 43 #endif /* PRESUNEUC */
44 44
45 45 #include "ex.h"
46 46 #include "ex_re.h"
47 47 #include "ex_tty.h"
48 48 #include "ex_vis.h"
49 49
50 50 /*
51 51 * Random routines, in alphabetical order.
52 52 */
53 53
54 54 int
55 55 any(int c, unsigned char *s)
56 56 {
57 57 int x;
58 58
59 59 while (x = *s++)
60 60 if (x == c)
61 61 return (1);
62 62 return (0);
63 63 }
64 64
65 65 int
66 66 backtab(int i)
67 67 {
68 68 int j;
69 69
70 70 j = i % value(vi_SHIFTWIDTH);
71 71 if (j == 0)
72 72 j = value(vi_SHIFTWIDTH);
73 73 i -= j;
74 74 if (i < 0)
75 75 i = 0;
76 76 return (i);
77 77 }
78 78
79 79 void
80 80 change(void)
81 81 {
82 82
83 83 tchng++;
84 84 chng = tchng;
85 85 }
86 86
87 87 /*
88 88 * Column returns the number of
89 89 * columns occupied by printing the
90 90 * characters through position cp of the
91 91 * current line.
92 92 */
93 93 int
94 94 column(unsigned char *cp)
95 95 {
96 96
97 97 if (cp == 0)
98 98 cp = &linebuf[LBSIZE - 2];
99 99 return (qcolumn(cp, (unsigned char *)0));
100 100 }
101 101
102 102 /* lcolumn is same as column except it returns number of columns
103 103 * occupied by characters before position
104 104 * cp of the current line
105 105 */
106 106 int
107 107 lcolumn(unsigned char *cp)
108 108 {
109 109
110 110 if (cp == 0)
111 111 cp = &linebuf[LBSIZE - 2];
112 112 return (nqcolumn(lastchr(linebuf, cp), (unsigned char *)0));
113 113 }
114 114
115 115 /*
116 116 * Ignore a comment to the end of the line.
117 117 * This routine eats the trailing newline so don't call donewline().
118 118 */
119 119 void
120 120 comment(void)
121 121 {
122 122 int c;
123 123
124 124 do {
125 125 c = getchar();
126 126 } while (c != '\n' && c != EOF);
127 127 if (c == EOF)
128 128 ungetchar(c);
129 129 }
130 130
131 131 void
132 132 Copy(unsigned char *to, unsigned char *from, int size)
133 133 {
134 134
135 135 if (size > 0)
136 136 do
137 137 *to++ = *from++;
138 138 while (--size > 0);
139 139 }
140 140
141 141 void
142 142 copyw(line *to, line *from, int size)
143 143 {
144 144
145 145 if (size > 0)
146 146 do
147 147 *to++ = *from++;
148 148 while (--size > 0);
149 149 }
150 150
151 151 void
152 152 copywR(line *to, line *from, int size)
153 153 {
154 154
155 155 while (--size >= 0)
156 156 to[size] = from[size];
157 157 }
158 158
159 159 int
160 160 ctlof(int c)
161 161 {
162 162
163 163 return (c == DELETE ? '?' : c | ('A' - 1));
164 164 }
165 165
166 166 void
167 167 dingdong(void)
168 168 {
169 169
170 170 if (flash_screen && value(vi_FLASH))
171 171 putpad((unsigned char *)flash_screen);
172 172 else if (value(vi_ERRORBELLS))
173 173 putpad((unsigned char *)bell);
174 174 }
175 175
176 176 int
177 177 fixindent(int indent)
178 178 {
179 179 int i;
180 180 unsigned char *cp;
181 181
182 182 i = whitecnt(genbuf);
183 183 cp = vpastwh(genbuf);
184 184 if (*cp == 0 && i == indent && linebuf[0] == 0) {
185 185 genbuf[0] = 0;
186 186 return (i);
187 187 }
188 188 CP(genindent(i), cp);
189 189 return (i);
190 190 }
191 191
192 192 void
193 193 filioerr(unsigned char *cp)
194 194 {
195 195 int oerrno = errno;
196 196
197 197 lprintf("\"%s\"", cp);
198 198 errno = oerrno;
199 199 syserror(1);
200 200 }
201 201
202 202 unsigned char *
203 203 genindent(indent)
204 204 int indent;
205 205 {
206 206 unsigned char *cp;
207 207
208 208 for (cp = genbuf; indent >= value(vi_TABSTOP); indent -= value(vi_TABSTOP))
209 209 *cp++ = '\t';
210 210 for (; indent > 0; indent--)
211 211 *cp++ = ' ';
212 212 return (cp);
213 213 }
214 214
215 215 void
216 216 getDOT(void)
↓ open down ↓ |
216 lines elided |
↑ open up ↑ |
217 217 {
218 218
219 219 getaline(*dot);
220 220 }
221 221
222 222 line *
223 223 getmark(c)
224 224 int c;
225 225 {
226 226 line *addr;
227 -
227 +
228 228 for (addr = one; addr <= dol; addr++)
229 229 if (names[c - 'a'] == (*addr &~ 01)) {
230 230 return (addr);
231 231 }
232 232 return (0);
233 233 }
234 234
235 235 void
236 236 ignnEOF(void)
237 237 {
238 238 int c = getchar();
239 239
240 240 if (c == EOF)
241 241 ungetchar(c);
242 242 else if (c=='"')
243 243 comment();
244 244 }
245 245
246 246 int
247 247 iswhite(int c)
248 248 {
249 249
250 250 return (c == ' ' || c == '\t');
251 251 }
252 252
253 253 int
254 254 junk(wchar_t c)
255 255 {
256 256
257 257 if (c && !value(vi_BEAUTIFY))
258 258 return (0);
259 259 if (c >= ' ' && c != DELETE)
260 260 return (0);
261 261 switch (c) {
262 262
263 263 case '\t':
264 264 case '\n':
265 265 case '\f':
266 266 return (0);
267 267
268 268 default:
269 269 return (1);
270 270 }
271 271 }
272 272
273 273 void
274 274 killed(void)
275 275 {
276 276
277 277 killcnt(addr2 - addr1 + 1);
278 278 }
279 279
280 280 void
281 281 killcnt(int cnt)
282 282 {
283 283 extern char *verbalize();
284 284
285 285 if (inopen) {
286 286 notecnt = cnt;
287 287 notenam = notesgn = (unsigned char *)"";
288 288 return;
289 289 }
290 290 if (!notable(cnt))
291 291 return;
292 292 if (value(vi_TERSE) == 0) {
293 293 verbalize(cnt, Command, "");
294 294 } else {
295 295 if (cnt == 1) {
296 296 viprintf(gettext("1 line"), cnt);
297 297 } else {
298 298 viprintf(gettext("%d lines"), cnt);
299 299 }
300 300 }
301 301 putNFL();
302 302 }
303 303
304 304 int
305 305 lineno(line *a)
306 306 {
307 307
308 308 return (a - zero);
309 309 }
310 310
311 311 int
312 312 lineDOL(void)
313 313 {
314 314
315 315 return (lineno(dol));
316 316 }
317 317
318 318 int
319 319 lineDOT(void)
320 320 {
321 321
322 322 return (lineno(dot));
323 323 }
324 324
325 325 void
326 326 markDOT(void)
327 327 {
328 328
329 329 markpr(dot);
330 330 }
331 331
332 332 void
333 333 markpr(line *which)
334 334 {
335 335
336 336 if ((inglobal == 0 || inopen) && which <= endcore) {
337 337 names['z'-'a'+1] = *which & ~01;
338 338 if (inopen)
339 339 ncols['z'-'a'+1] = cursor;
340 340 }
341 341 }
342 342
343 343 int
344 344 markreg(int c)
345 345 {
346 346
347 347 if (c == '\'' || c == '`')
348 348 return ('z' + 1);
349 349 if (c >= 'a' && c <= 'z')
350 350 return (c);
351 351 return (0);
352 352 }
353 353
354 354 /*
355 355 * Mesg decodes the terse/verbose strings. Thus
356 356 * 'xxx@yyy' -> 'xxx' if terse, else 'xxx yyy'
357 357 * 'xxx|yyy' -> 'xxx' if terse, else 'yyy'
358 358 * All others map to themselves.
359 359 */
360 360 /*
361 361 * The feature described above was disabled for localizable messaging.
362 362 */
363 363 unsigned char *
364 364 mesg(str)
365 365 unsigned char *str;
366 366 {
367 367 unsigned char *cp;
368 368
369 369 str = (unsigned char *)strcpy(genbuf, str);
370 370 /* commented out for localizable messaging */
371 371 /* for (cp = str; *cp; cp++)
372 372 switch (*cp) {
373 373
374 374 case '@':
375 375 if (value(vi_TERSE))
376 376 *cp = 0;
377 377 else
378 378 *cp = ' ';
379 379 break;
380 380
381 381 case '|':
382 382 if (value(vi_TERSE) == 0)
383 383 return (cp + 1);
384 384 *cp = 0;
385 385 break;
386 386 } */
387 387 return (str);
388 388 }
389 389
390 390 /*VARARGS2*/
391 391 void
392 392 merror(unsigned char *seekpt, int i)
393 393 {
394 394 unsigned char *cp = linebuf;
395 395
396 396 if (seekpt == 0)
397 397 return;
398 398 merror1(seekpt);
399 399 if (*cp == '\n')
400 400 putnl(), cp++;
401 401 if (inopen > 0 && clr_eol)
402 402 vclreol();
403 403 if (enter_standout_mode && exit_bold)
404 404 putpad((unsigned char *)enter_standout_mode);
405 405 #ifdef PRESUNEUC
406 406 viprintf(mesg(cp), i);
407 407 #else
408 408 viprintf((char *)mesg(cp), i);
409 409 #endif /* PRESUNEUC */
410 410 if (enter_standout_mode && exit_bold)
411 411 putpad((unsigned char *)exit_bold);
412 412 }
413 413
414 414 void
415 415 merror1(unsigned char *seekpt)
416 416 {
417 417
418 418 strcpy(linebuf, seekpt);
419 419 }
420 420
421 421 #define MAXDATA (56*1024)
422 422 int
423 423 morelines(void)
424 424 {
425 425 unsigned char *end;
426 426
427 427 if ((int) sbrk(1024 * sizeof (line)) == -1) {
428 428 if (endcore >= (line *) MAXDATA)
429 429 return -1;
430 430 end = (unsigned char *) MAXDATA;
431 431 /*
432 432 * Ask for end+2 sice we want end to be the last used location.
433 433 */
434 434 while (brk(end+2) == -1)
435 435 end -= 64;
436 436 if (end <= (unsigned char *) endcore)
437 437 return -1;
438 438 endcore = (line *) end;
439 439 } else {
440 440 endcore += 1024;
441 441 }
442 442 return (0);
443 443 }
444 444
445 445 void
446 446 nonzero(void)
447 447 {
448 448
449 449 if (addr1 == zero) {
450 450 notempty();
451 451 error(value(vi_TERSE) ? gettext("Nonzero address required") :
452 452 gettext("Nonzero address required on this command"));
453 453 }
454 454 }
455 455
456 456 int
457 457 notable(int i)
458 458 {
459 459
460 460 return (hush == 0 && !inglobal && i > value(vi_REPORT));
461 461 }
462 462
463 463
464 464 void
465 465 notempty(void)
466 466 {
467 467
468 468 if (dol == zero)
469 469 error(value(vi_TERSE) ? gettext("No lines") :
470 470 gettext("No lines in the buffer"));
471 471 }
472 472
473 473
474 474 void
475 475 netchHAD(int cnt)
476 476 {
477 477
478 478 netchange(lineDOL() - cnt);
479 479 }
480 480
481 481 void
482 482 netchange(int i)
483 483 {
484 484 unsigned char *cp;
485 485
486 486 if (i > 0)
487 487 notesgn = cp = (unsigned char *)"more ";
488 488 else
489 489 notesgn = cp = (unsigned char *)"fewer ", i = -i;
490 490 if (inopen) {
491 491 notecnt = i;
492 492 notenam = (unsigned char *)"";
493 493 return;
494 494 }
495 495 if (!notable(i))
496 496 return;
497 497 if (*cp == 'm') /* for ease of messge localization */
498 498 #ifdef PRESUNEUC
499 499 viprintf(mesg(value(vi_TERSE) ?
500 500 #else
501 501 viprintf((char *)mesg(value(vi_TERSE) ?
502 502 #endif /* PRESUNEUC */
503 503 gettext("%d more lines") :
504 504 /*
505 505 * TRANSLATION_NOTE
506 506 * Reference order of arguments must not
507 507 * be changed using '%digit$', since vi's
508 508 * viprintf() does not support it.
509 509 */
510 510 gettext("%d more lines in file after %s")), i, Command);
511 511 else
512 512 #ifdef PRESUNEUC
513 513 viprintf(mesg(value(vi_TERSE) ?
514 514 #else
515 515 viprintf((char *)mesg(value(vi_TERSE) ?
516 516 #endif /* PRESUNEUC */
517 517 gettext("%d fewer lines") :
518 518 /*
519 519 * TRANSLATION_NOTE
520 520 * Reference order of arguments must not
521 521 * be changed using '%digit$', since vi's
522 522 * viprintf() does not support it.
523 523 */
524 524 gettext("%d fewer lines in file after %s")), i, Command);
525 525 putNFL();
526 526 }
527 527
528 528 void
529 529 putmark(line *addr)
530 530 {
531 531
532 532 putmk1(addr, putline());
533 533 }
534 534
535 535 void
536 536 putmk1(line *addr, int n)
537 537 {
538 538 line *markp;
539 539 int oldglobmk;
540 540
541 541 oldglobmk = *addr & 1;
542 542 *addr &= ~1;
543 543 for (markp = (anymarks ? names : &names['z'-'a'+1]);
544 544 markp <= &names['z'-'a'+1]; markp++)
545 545 if (*markp == *addr)
546 546 *markp = n;
547 547 *addr = n | oldglobmk;
548 548 }
549 549
550 550 unsigned char *
551 551 plural(i)
552 552 long i;
553 553 {
554 554
555 555 return (i == 1 ? (unsigned char *)"" : (unsigned char *)"s");
556 556 }
557 557
558 558 int qcount();
559 559 short vcntcol;
560 560
561 561 int
562 562 qcolumn(unsigned char *lim, unsigned char *gp)
563 563 {
564 564 int x, length;
565 565 int col;
566 566 wchar_t wchar;
567 567 int (*OO)();
568 568
↓ open down ↓ |
331 lines elided |
↑ open up ↑ |
569 569 OO = Outchar;
570 570 Outchar = qcount;
571 571 vcntcol = 0;
572 572 if (lim != NULL) {
573 573 if(lim == linebuf - 1 || lim == &linebuf[LBSIZE-2])
574 574 length = 1;
575 575 else
576 576 length = mbtowc(&wchar, (char *)lim, MULTI_BYTE_MAX);
577 577 if(length < 0)
578 578 length = 1;
579 - x = lim[length];
579 + x = lim[length];
580 580 lim[length] = 0;
581 581 }
582 582 pline(0);
583 583 if (lim != NULL)
584 584 lim[length] = x;
585 585 if(length > 1 && !gp) {
586 586 /* put cursor at beginning of multibyte character */
587 587 if ((col = wcwidth(wchar)) < 0)
588 588 col = 0;
589 589 vcntcol = vcntcol - col + 1;
590 590 }
591 591 if (gp)
592 592 while (*gp) {
593 593 length = mbtowc(&wchar, (char *)gp, MULTI_BYTE_MAX);
594 594 if(length < 0) {
595 595 putoctal = 1;
596 596 putchar(*gp++);
597 597 putoctal = 0;
598 598 } else {
599 599 putchar(wchar);
600 600 gp += length;
601 601 }
602 602 }
603 603 Outchar = OO;
604 604 return (vcntcol);
605 605 }
606 606
607 607 /* This routine puts cursor after multibyte character */
608 608 int
609 609 nqcolumn(unsigned char *lim, unsigned char *gp)
610 610 {
611 611 int x, length;
612 612 wchar_t wchar;
613 613 int (*OO)();
614 614
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
615 615 OO = Outchar;
616 616 Outchar = qcount;
617 617 vcntcol = 0;
618 618 if (lim != NULL) {
619 619 if(lim == linebuf - 1 || lim == &linebuf[LBSIZE-2])
620 620 length = 1;
621 621 else
622 622 length = mbtowc(&wchar, (char *)lim, MULTI_BYTE_MAX);
623 623 if(length < 0)
624 624 length = 1;
625 - x = lim[length];
625 + x = lim[length];
626 626 lim[length] = 0;
627 627 }
628 628 pline(0);
629 629 if (lim != NULL)
630 630 lim[length] = x;
631 631 if (gp)
632 632 while (*gp) {
633 633 length = mbtowc(&wchar, (char *)gp, MULTI_BYTE_MAX);
634 634 if(length < 0) {
635 635 putoctal = 1;
636 636 putchar(*gp++);
637 637 putoctal = 0;
638 638 } else {
639 639 putchar(wchar);
640 640 gp += length;
641 641 }
642 642 }
643 643 Outchar = OO;
644 644 return (vcntcol);
645 645 }
646 646
647 647 int
648 648 qcount(c)
649 649 wchar_t c;
650 650 {
651 651 int cols;
652 652 #ifndef PRESUNEUC
653 653 int remcols;
654 654 short OWCOLS;
655 655 #endif /* PRESUNEUC */
656 656
657 657 if (c == '\t') {
658 658 vcntcol += value(vi_TABSTOP) - vcntcol % value(vi_TABSTOP);
659 659 return (0);
660 660 }
661 661 #ifdef PRESUNEUC
662 662 if ((cols = wcwidth(c)) > 0)
663 663 vcntcol += cols;
664 664 #else
665 665 if ((cols = wcwidth(c)) < 0)
666 666 cols = 0;
667 667 OWCOLS = WCOLS;
668 668 if (WCOLS == 0)
669 669 WCOLS = columns;
670 670 if ((mc_wrap) == 1 && (remcols = (WCOLS - (vcntcol % WCOLS))) < cols)
671 671 vcntcol += remcols;
672 672 WCOLS = OWCOLS;
673 673 vcntcol += cols;
674 674 #endif /* PRESUNEUC */
675 675 return (0);
676 676 }
677 677
678 678 void
679 679 reverse(line *a1, line *a2)
680 680 {
681 681 line t;
682 682
683 683 for (;;) {
684 684 t = *--a2;
685 685 if (a2 <= a1)
686 686 return;
687 687 *a2 = *a1;
688 688 *a1++ = t;
689 689 }
690 690 }
691 691
692 692 void
693 693 save(line *a1, line *a2)
694 694 {
695 695 int more;
696 696
697 697 if (!FIXUNDO)
698 698 return;
699 699 #ifdef UNDOTRACE
700 700 if (trace)
701 701 vudump("before save");
702 702 #endif
703 703 undkind = UNDNONE;
704 704 undadot = dot;
705 705 more = (a2 - a1 + 1) - (unddol - dol);
706 706 while (more > (endcore - truedol))
707 707 if (morelines() < 0)
708 708 error(value(vi_TERSE) ? gettext("Out of memory") :
709 709 gettext("Out of memory saving lines for undo - try using ed"));
710 710 if (more)
711 711 (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1,
712 712 (truedol - unddol));
713 713 unddol += more;
714 714 truedol += more;
715 715 copyw(dol + 1, a1, a2 - a1 + 1);
716 716 undkind = UNDALL;
717 717 unddel = a1 - 1;
718 718 undap1 = a1;
719 719 undap2 = a2 + 1;
720 720 #ifdef UNDOTRACE
721 721 if (trace)
722 722 vudump("after save");
723 723 #endif
724 724 }
725 725
726 726 void
727 727 save12(void)
728 728 {
729 729
730 730 save(addr1, addr2);
731 731 }
732 732
733 733 void
734 734 saveall(void)
735 735 {
736 736
737 737 save(one, dol);
738 738 }
739 739
740 740 int
741 741 span(void)
742 742 {
743 743
744 744 return (addr2 - addr1 + 1);
745 745 }
746 746
747 747 void
748 748 sync(void)
749 749 {
750 750
751 751 chng = 0;
752 752 tchng = 0;
753 753 xchng = 0;
754 754 }
755 755
756 756
757 757 int
758 758 skipwh(void)
759 759 {
760 760 int wh;
761 761
762 762 wh = 0;
763 763 while (iswhite(peekchar())) {
764 764 wh++;
765 765 ignchar();
766 766 }
767 767 return (wh);
768 768 }
769 769
770 770 /*VARARGS2*/
771 771 void
772 772 smerror(unsigned char *seekpt, unsigned char *cp)
773 773 {
774 774
775 775 errcnt++;
776 776 merror1(seekpt);
777 777 if (inopen && clr_eol)
778 778 vclreol();
779 779 if (enter_standout_mode && exit_bold)
780 780 putpad((unsigned char *)enter_standout_mode);
781 781 lprintf(mesg(linebuf), cp);
782 782 if (enter_standout_mode && exit_bold)
783 783 putpad((unsigned char *)exit_bold);
784 784 }
785 785
786 786 unsigned char *
787 787 strend(cp)
788 788 unsigned char *cp;
789 789 {
790 790
791 791 while (*cp)
792 792 cp++;
793 793 return (cp);
794 794 }
795 795
796 796 void
797 797 strcLIN(unsigned char *dp)
798 798 {
799 799
800 800 CP(linebuf, dp);
801 801 }
802 802
803 803 /*
804 804 * A system error has occurred that we need to perror.
805 805 * danger is true if we are unsure of the contents of
806 806 * the file or our buffer, e.g. a write error in the
807 807 * middle of a write operation, or a temp file error.
808 808 */
809 809 void
810 810 syserror(int danger)
811 811 {
812 812 int e = errno;
813 813 char *errstr;
814 814 extern char *strerror();
815 815
816 816 dirtcnt = 0;
817 817 putchar(' ');
818 818 if (danger)
819 819 edited = 0; /* for temp file errors, for example */
820 820 if ((errstr = strerror(e)) != NULL)
821 821 error(errstr);
822 822 else
823 823 error(gettext("System error %d"), e);
824 824 }
825 825
826 826 /*
827 827 * Return the column number that results from being in column col and
828 828 * hitting a tab, where tabs are set every ts columns. Work right for
829 829 * the case where col > columns, even if ts does not divide columns.
830 830 */
831 831 int
832 832 tabcol(int col, int ts)
833 833 {
834 834 int offset, result;
835 835
836 836 if (col >= columns) {
837 837 offset = columns * (col/columns);
838 838 col -= offset;
839 839 } else
840 840 offset = 0;
841 841 result = col + ts - (col % ts) + offset;
842 842 return (result);
843 843 }
844 844
845 845 unsigned char *
846 846 vfindcol(i)
847 847 int i;
848 848 {
849 849 unsigned char *cp, *oldcp;
850 850 int (*OO)() = Outchar;
851 851 int length;
852 852 unsigned char x;
853 853 wchar_t wchar;
854 854
855 855 Outchar = qcount;
856 856 (void) qcolumn(linebuf - 1, (unsigned char *)NOSTR);
857 857 for (cp = linebuf; *cp && vcntcol < i; ) {
858 858 oldcp = cp;
859 859 length = mbtowc(&wchar, (char *)cp, MULTI_BYTE_MAX);
860 860 if(length < 0) {
861 861 putoctal = 1;
862 862 putchar(*cp++);
863 863 putoctal = 0;
864 864 } else {
865 865 putchar(wchar);
866 866 cp += length;
867 867 }
868 868 }
869 869 if (cp != linebuf)
870 870 cp = oldcp;
871 871 Outchar = OO;
872 872 return (cp);
873 873 }
874 874
875 875 unsigned char *
876 876 vskipwh(cp)
877 877 unsigned char *cp;
878 878 {
879 879
880 880 while (iswhite(*cp) && cp[1])
881 881 cp++;
882 882 return (cp);
883 883 }
884 884
885 885
886 886 unsigned char *
887 887 vpastwh(cp)
888 888 unsigned char *cp;
889 889 {
890 890
891 891 while (iswhite(*cp))
892 892 cp++;
893 893 return (cp);
894 894 }
895 895
896 896 int
897 897 whitecnt(unsigned char *cp)
898 898 {
899 899 int i;
900 900
901 901 i = 0;
902 902 for (;;)
903 903 switch (*cp++) {
904 904
905 905 case '\t':
906 906 i += value(vi_TABSTOP) - i % value(vi_TABSTOP);
907 907 break;
908 908
909 909 case ' ':
910 910 i++;
911 911 break;
912 912
913 913 default:
914 914 return (i);
915 915 }
916 916 }
↓ open down ↓ |
281 lines elided |
↑ open up ↑ |
917 917
918 918 void
919 919 markit(line *addr)
920 920 {
921 921
922 922 if (addr != dot && addr >= one && addr <= dol)
923 923 markDOT();
924 924 }
925 925
926 926 /*
927 - * The following code is defensive programming against a bug in the
928 - * pdp-11 overlay implementation. Sometimes it goes nuts and asks
929 - * for an overlay with some garbage number, which generates an emt
930 - * trap. This is a less than elegant solution, but it is somewhat
931 - * better than core dumping and losing your work, leaving your tty
932 - * in a weird state, etc.
933 - */
934 -int _ovno;
935 -
936 -/*ARGSUSED*/
937 -void
938 -onemt(sig)
939 -int sig;
940 -{
941 - int oovno;
942 -
943 - signal(SIGEMT, onemt);
944 - oovno = _ovno;
945 - /* 2 and 3 are valid on 11/40 type vi, so */
946 - if (_ovno < 0 || _ovno > 3)
947 - _ovno = 0;
948 - error(value(vi_TERSE) ? gettext("emt trap, _ovno is %d ") :
949 -gettext("emt trap, _ovno is %d - try again"));
950 -}
951 -
952 -/*
953 927 * When a hangup occurs our actions are similar to a preserve
954 928 * command. If the buffer has not been [Modified], then we do
955 929 * nothing but remove the temporary files and exit.
956 930 * Otherwise, we sync the temp file and then attempt a preserve.
957 931 * If the preserve succeeds, we unlink our temp files.
958 932 * If the preserve fails, we leave the temp files as they are
959 933 * as they are a backup even without preservation if they
960 934 * are not removed.
961 935 */
962 936
963 937 /*ARGSUSED*/
964 -void
938 +void
965 939 onhup(sig)
966 940 int sig;
967 941 {
968 942
969 943 /*
970 944 * USG tty driver can send multiple HUP's!!
971 945 */
972 946 signal(SIGINT, SIG_IGN);
973 947 signal(SIGHUP, SIG_IGN);
974 948 if (chng == 0) {
975 949 cleanup(1);
976 950 exit(++errcnt);
977 951 }
978 952 if (setexit() == 0) {
979 953 if (preserve()) {
980 954 cleanup(1);
981 955 exit(++errcnt);
982 956 }
983 957 }
984 958 if (kflag)
985 959 crypt_close(perm);
986 960 if (xtflag)
987 961 crypt_close(tperm);
988 962 exit(++errcnt);
989 963 }
990 964
991 965 /*
992 966 * Similar to onhup. This happens when any random core dump occurs,
993 967 * e.g. a bug in vi. We preserve the file and then generate a core.
994 968 */
995 969 void oncore(sig)
996 970 int sig;
997 971 {
998 972 static int timescalled = 0;
999 973 char *messagep; /* for message localization */
1000 974
1001 975 /*
1002 976 * USG tty driver can send multiple HUP's!!
1003 977 */
1004 978 signal(SIGINT, SIG_IGN);
1005 979 signal(SIGHUP, SIG_IGN);
1006 980 signal(sig, SIG_DFL); /* Insure that we don't catch it again */
1007 981 messagep = (char *)gettext("\r\nYour file has been preserved\r\n");
1008 982 if (timescalled++ == 0 && chng && setexit() == 0) {
1009 983 if (inopen)
1010 984 vsave();
1011 985 (void) preserve();
1012 986 write(1, messagep, strlen(messagep));
1013 987 }
1014 988 if (timescalled < 2) {
1015 989 normal(normf);
1016 990 cleanup(2);
1017 991 kill(getpid(), sig); /* Resend ourselves the same signal */
1018 992 /* We won't get past here */
1019 993 }
1020 994 if (kflag)
1021 995 crypt_close(perm);
1022 996 if (xtflag)
1023 997 crypt_close(tperm);
1024 998 exit(++errcnt);
1025 999 }
1026 1000
↓ open down ↓ |
52 lines elided |
↑ open up ↑ |
1027 1001 /*
1028 1002 * An interrupt occurred. Drain any output which
1029 1003 * is still in the output buffering pipeline.
1030 1004 * Catch interrupts again. Unless we are in visual
1031 1005 * reset the output state (out of -nl mode, e.g).
1032 1006 * Then like a normal error (with the \n before Interrupt
1033 1007 * suppressed in visual mode).
1034 1008 */
1035 1009
1036 1010 /*ARGSUSED*/
1037 -void
1011 +void
1038 1012 onintr(sig)
1039 1013 int sig;
1040 1014 {
1041 1015 #ifndef CBREAK
1042 1016 signal(SIGINT, onintr);
1043 1017 #else
1044 1018 signal(SIGINT, inopen ? vintr : onintr);
1045 1019 #endif
1046 1020 cancelalarm();
1047 1021 draino();
1048 1022 if (!inopen) {
1049 1023 pstop();
1050 1024 setlastchar('\n');
1051 1025 #ifdef CBREAK
1052 1026 }
1053 1027 #else
1054 1028 } else
1055 1029 vraw();
1056 1030 #endif
1057 1031 error(gettext("\nInterrupt") + (inopen!=0));
1058 1032 }
1059 1033
1060 1034 /*
1061 1035 * If we are interruptible, enable interrupts again.
1062 1036 * In some critical sections we turn interrupts off,
1063 1037 * but not very often.
1064 1038 */
1065 1039 void
1066 1040 setrupt(void)
1067 1041 {
1068 1042
1069 1043 if (ruptible) {
1070 1044 #ifndef CBREAK
1071 1045 signal(SIGINT, onintr);
1072 1046 #else
1073 1047 signal(SIGINT, inopen ? vintr : onintr);
1074 1048 #endif
1075 1049 #ifdef SIGTSTP
1076 1050 if (dosusp)
1077 1051 signal(SIGTSTP, onsusp);
1078 1052 #endif
1079 1053 }
1080 1054 }
1081 1055
1082 1056 int
1083 1057 preserve(void)
1084 1058 {
1085 1059
1086 1060 #ifdef VMUNIX
1087 1061 tflush();
1088 1062 #endif
1089 1063 synctmp();
1090 1064 pid = fork();
1091 1065 if (pid < 0)
1092 1066 return (0);
1093 1067 if (pid == 0) {
1094 1068 close(0);
1095 1069 dup(tfile);
1096 1070 execlp(EXPRESERVE, "expreserve", (char *) 0);
1097 1071 exit(++errcnt);
1098 1072 }
1099 1073 waitfor();
1100 1074 if (rpid == pid && status == 0)
1101 1075 return (1);
1102 1076 return (0);
1103 1077 }
1104 1078
1105 1079 #ifndef V6
1106 1080 void exit(i)
1107 1081 int i;
1108 1082 {
1109 1083
1110 1084 extern void _exit(int) __NORETURN;
1111 1085 #ifdef TRACE
1112 1086 if (trace)
1113 1087 fclose(trace);
1114 1088 #endif
1115 1089 _exit(i);
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
1116 1090 }
1117 1091 #endif
1118 1092
1119 1093 #ifdef SIGTSTP
1120 1094 /*
1121 1095 * We have just gotten a susp. Suspend and prepare to resume.
1122 1096 */
1123 1097 extern void redraw();
1124 1098
1125 1099 /*ARGSUSED*/
1126 -void
1100 +void
1127 1101 onsusp(sig)
1128 1102 int sig;
1129 1103 {
1130 1104 ttymode f;
1131 1105 int savenormtty;
1132 1106
1133 1107 f = setty(normf);
1134 1108 vnfl();
1135 1109 putpad((unsigned char *)exit_ca_mode);
1136 1110 flush();
1137 1111 resetterm();
1138 1112 savenormtty = normtty;
1139 1113 normtty = 0;
1140 1114
1141 1115 signal(SIGTSTP, SIG_DFL);
1142 1116 kill(0, SIGTSTP);
1143 1117
1144 1118 /* the pc stops here */
1145 1119
1146 1120 signal(SIGTSTP, onsusp);
1147 1121 normtty = savenormtty;
1148 1122 vcontin(0);
1149 1123 flush();
1150 1124 setty(f);
1151 1125 if (!inopen)
1152 1126 error(0);
1153 1127 else {
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
1154 1128 if(vcnt < 0) {
1155 1129 vcnt = -vcnt;
1156 1130 if(state == VISUAL)
1157 1131 vclear();
1158 1132 else if(state == CRTOPEN)
1159 1133 vcnt = 0;
1160 1134 }
1161 1135 vdirty(0, lines);
1162 1136 if (sig)
1163 1137 vrepaint(cursor);
1164 - }
1138 + }
1165 1139 }
1166 1140 #endif
1167 1141
1168 1142 unsigned char *nextchr(cursor)
1169 1143 unsigned char *cursor;
1170 1144 {
1171 1145
1172 1146 wchar_t wchar;
1173 1147 int length;
1174 1148 length = mbtowc(&wchar, (char *)cursor, MULTI_BYTE_MAX);
1175 1149 if(length <= 0)
1176 1150 return(++cursor);
1177 1151 return(cursor + length);
1178 1152 }
1179 1153
1180 1154 unsigned char *lastchr(linebuf, cursor)
1181 1155 unsigned char *linebuf, *cursor;
1182 1156 {
1183 1157 wchar_t wchar;
1184 1158 int length;
1185 1159 unsigned char *ccursor, *ocursor;
1186 1160 if(cursor == linebuf)
1187 1161 return(linebuf - 1);
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
1188 1162 ccursor = ocursor = linebuf;
1189 1163 while(ccursor < cursor) {
1190 1164 length = mbtowc(&wchar, (char *)ccursor, MULTI_BYTE_MAX);
1191 1165 ocursor = ccursor;
1192 1166 if(length <= 0)
1193 1167 ccursor++;
1194 1168 else
1195 1169 ccursor += length;
1196 1170 }
1197 1171 return(ocursor);
1198 -}
1172 +}
1199 1173
1200 1174 int
1201 1175 ixlatctl(int flag)
1202 1176 {
1203 1177 static struct strioctl sb = {0, 0, 0, 0};
1204 1178
1205 1179 if (!(MULTI_BYTE_MAX > 1))
1206 1180 return (0);
1207 1181
1208 1182 switch (flag) {
1209 1183 case 0:
1210 1184 sb.ic_cmd = EUC_MSAVE;
1211 1185 sb.ic_len = 0;
1212 1186 sb.ic_dp = 0;
1213 1187 if (ioctl(0, I_STR, &sb) < 0)
1214 1188 return (-1);
1215 1189 return (0);
1216 1190 case 1:
1217 1191 sb.ic_cmd = EUC_MREST;
1218 1192 sb.ic_len = 0;
1219 1193 sb.ic_dp = 0;
1220 1194 if (ioctl(0, I_STR, &sb) < 0)
1221 1195 return (-1);
1222 1196 return (0);
1223 1197 case 11:
1224 1198 return (0);
1225 1199 default:
1226 1200 return (-1);
1227 1201 }
1228 1202 }
1229 1203 #ifndef PRESUNEUC
1230 1204
1231 1205 /* locale specific initialization */
1232 1206 void
1233 1207 localize(void)
1234 1208 {
1235 1209 wchar_t fillerchar;
1236 1210 extern int wdchkind();
1237 1211 extern int wdbindf();
1238 1212 extern wchar_t *wddelim();
1239 1213 extern wchar_t mcfiller();
1240 1214
1241 1215 wdwc = wdchkind;
1242 1216 wdbdg = wdbindf;
1243 1217 wddlm = wddelim;
1244 1218 mcfllr = mcfiller;
1245 1219 mc_wrap = 1;
1246 1220 fillerchar = mcfiller();
1247 1221 mc_filler = isascii(fillerchar) ? (fillerchar & 0x7f) : '~';
1248 1222 }
1249 1223 #endif /* PRESUNEUC */
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX