10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 23*802Scf46844 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 280Sstevel@tonic-gate /* All Rights Reserved */ 290Sstevel@tonic-gate 300Sstevel@tonic-gate 310Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */ 320Sstevel@tonic-gate 330Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 340Sstevel@tonic-gate 350Sstevel@tonic-gate #include <sys/stropts.h> 360Sstevel@tonic-gate #include <sys/eucioctl.h> 370Sstevel@tonic-gate #ifndef PRESUNEUC 380Sstevel@tonic-gate #include <locale.h> 390Sstevel@tonic-gate /* Undef putchar/getchar if they're defined. */ 400Sstevel@tonic-gate #ifdef putchar 410Sstevel@tonic-gate # undef putchar 420Sstevel@tonic-gate #endif 430Sstevel@tonic-gate #ifdef getchar 440Sstevel@tonic-gate # undef getchar 450Sstevel@tonic-gate #endif 460Sstevel@tonic-gate #endif /* PRESUNEUC */ 470Sstevel@tonic-gate 480Sstevel@tonic-gate #include "ex.h" 490Sstevel@tonic-gate #include "ex_re.h" 500Sstevel@tonic-gate #include "ex_tty.h" 510Sstevel@tonic-gate #include "ex_vis.h" 520Sstevel@tonic-gate 530Sstevel@tonic-gate /* 540Sstevel@tonic-gate * Random routines, in alphabetical order. 550Sstevel@tonic-gate */ 560Sstevel@tonic-gate 57*802Scf46844 int 58*802Scf46844 any(int c, unsigned char *s) 590Sstevel@tonic-gate { 60*802Scf46844 int x; 610Sstevel@tonic-gate 620Sstevel@tonic-gate while (x = *s++) 630Sstevel@tonic-gate if (x == c) 640Sstevel@tonic-gate return (1); 650Sstevel@tonic-gate return (0); 660Sstevel@tonic-gate } 670Sstevel@tonic-gate 68*802Scf46844 int 69*802Scf46844 backtab(int i) 700Sstevel@tonic-gate { 71*802Scf46844 int j; 720Sstevel@tonic-gate 730Sstevel@tonic-gate j = i % value(vi_SHIFTWIDTH); 740Sstevel@tonic-gate if (j == 0) 750Sstevel@tonic-gate j = value(vi_SHIFTWIDTH); 760Sstevel@tonic-gate i -= j; 770Sstevel@tonic-gate if (i < 0) 780Sstevel@tonic-gate i = 0; 790Sstevel@tonic-gate return (i); 800Sstevel@tonic-gate } 810Sstevel@tonic-gate 82*802Scf46844 void 83*802Scf46844 change(void) 840Sstevel@tonic-gate { 850Sstevel@tonic-gate 860Sstevel@tonic-gate tchng++; 870Sstevel@tonic-gate chng = tchng; 880Sstevel@tonic-gate } 890Sstevel@tonic-gate 900Sstevel@tonic-gate /* 910Sstevel@tonic-gate * Column returns the number of 920Sstevel@tonic-gate * columns occupied by printing the 930Sstevel@tonic-gate * characters through position cp of the 940Sstevel@tonic-gate * current line. 950Sstevel@tonic-gate */ 96*802Scf46844 int 97*802Scf46844 column(unsigned char *cp) 980Sstevel@tonic-gate { 990Sstevel@tonic-gate 1000Sstevel@tonic-gate if (cp == 0) 1010Sstevel@tonic-gate cp = &linebuf[LBSIZE - 2]; 102*802Scf46844 return (qcolumn(cp, (unsigned char *)0)); 1030Sstevel@tonic-gate } 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate /* lcolumn is same as column except it returns number of columns 1060Sstevel@tonic-gate * occupied by characters before position 1070Sstevel@tonic-gate * cp of the current line 1080Sstevel@tonic-gate */ 109*802Scf46844 int 110*802Scf46844 lcolumn(unsigned char *cp) 1110Sstevel@tonic-gate { 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate if (cp == 0) 1140Sstevel@tonic-gate cp = &linebuf[LBSIZE - 2]; 115*802Scf46844 return (nqcolumn(lastchr(linebuf, cp), (unsigned char *)0)); 1160Sstevel@tonic-gate } 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate /* 1190Sstevel@tonic-gate * Ignore a comment to the end of the line. 1200Sstevel@tonic-gate * This routine eats the trailing newline so don't call donewline(). 1210Sstevel@tonic-gate */ 122*802Scf46844 void 123*802Scf46844 comment(void) 1240Sstevel@tonic-gate { 125*802Scf46844 int c; 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate do { 1280Sstevel@tonic-gate c = getchar(); 1290Sstevel@tonic-gate } while (c != '\n' && c != EOF); 1300Sstevel@tonic-gate if (c == EOF) 1310Sstevel@tonic-gate ungetchar(c); 1320Sstevel@tonic-gate } 1330Sstevel@tonic-gate 134*802Scf46844 void 135*802Scf46844 Copy(unsigned char *to, unsigned char *from, int size) 1360Sstevel@tonic-gate { 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate if (size > 0) 1390Sstevel@tonic-gate do 1400Sstevel@tonic-gate *to++ = *from++; 1410Sstevel@tonic-gate while (--size > 0); 1420Sstevel@tonic-gate } 1430Sstevel@tonic-gate 144*802Scf46844 void 145*802Scf46844 copyw(line *to, line *from, int size) 1460Sstevel@tonic-gate { 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate if (size > 0) 1490Sstevel@tonic-gate do 1500Sstevel@tonic-gate *to++ = *from++; 1510Sstevel@tonic-gate while (--size > 0); 1520Sstevel@tonic-gate } 1530Sstevel@tonic-gate 154*802Scf46844 void 155*802Scf46844 copywR(line *to, line *from, int size) 1560Sstevel@tonic-gate { 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate while (--size >= 0) 1590Sstevel@tonic-gate to[size] = from[size]; 1600Sstevel@tonic-gate } 1610Sstevel@tonic-gate 162*802Scf46844 int 163*802Scf46844 ctlof(int c) 1640Sstevel@tonic-gate { 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate return (c == DELETE ? '?' : c | ('A' - 1)); 1670Sstevel@tonic-gate } 1680Sstevel@tonic-gate 169*802Scf46844 void 170*802Scf46844 dingdong(void) 1710Sstevel@tonic-gate { 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate if (flash_screen && value(vi_FLASH)) 174*802Scf46844 putpad((unsigned char *)flash_screen); 1750Sstevel@tonic-gate else if (value(vi_ERRORBELLS)) 176*802Scf46844 putpad((unsigned char *)bell); 1770Sstevel@tonic-gate } 1780Sstevel@tonic-gate 179*802Scf46844 int 180*802Scf46844 fixindent(int indent) 1810Sstevel@tonic-gate { 182*802Scf46844 int i; 183*802Scf46844 unsigned char *cp; 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate i = whitecnt(genbuf); 1860Sstevel@tonic-gate cp = vpastwh(genbuf); 1870Sstevel@tonic-gate if (*cp == 0 && i == indent && linebuf[0] == 0) { 1880Sstevel@tonic-gate genbuf[0] = 0; 1890Sstevel@tonic-gate return (i); 1900Sstevel@tonic-gate } 1910Sstevel@tonic-gate CP(genindent(i), cp); 1920Sstevel@tonic-gate return (i); 1930Sstevel@tonic-gate } 1940Sstevel@tonic-gate 195*802Scf46844 void 196*802Scf46844 filioerr(unsigned char *cp) 1970Sstevel@tonic-gate { 198*802Scf46844 int oerrno = errno; 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate lprintf("\"%s\"", cp); 2010Sstevel@tonic-gate errno = oerrno; 2020Sstevel@tonic-gate syserror(1); 2030Sstevel@tonic-gate } 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate unsigned char * 2060Sstevel@tonic-gate genindent(indent) 207*802Scf46844 int indent; 2080Sstevel@tonic-gate { 209*802Scf46844 unsigned char *cp; 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate for (cp = genbuf; indent >= value(vi_TABSTOP); indent -= value(vi_TABSTOP)) 2120Sstevel@tonic-gate *cp++ = '\t'; 2130Sstevel@tonic-gate for (; indent > 0; indent--) 2140Sstevel@tonic-gate *cp++ = ' '; 2150Sstevel@tonic-gate return (cp); 2160Sstevel@tonic-gate } 2170Sstevel@tonic-gate 218*802Scf46844 void 219*802Scf46844 getDOT(void) 2200Sstevel@tonic-gate { 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate getline(*dot); 2230Sstevel@tonic-gate } 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate line * 2260Sstevel@tonic-gate getmark(c) 227*802Scf46844 int c; 2280Sstevel@tonic-gate { 229*802Scf46844 line *addr; 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate for (addr = one; addr <= dol; addr++) 2320Sstevel@tonic-gate if (names[c - 'a'] == (*addr &~ 01)) { 2330Sstevel@tonic-gate return (addr); 2340Sstevel@tonic-gate } 2350Sstevel@tonic-gate return (0); 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate 238*802Scf46844 void 239*802Scf46844 ignnEOF(void) 2400Sstevel@tonic-gate { 241*802Scf46844 int c = getchar(); 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate if (c == EOF) 2440Sstevel@tonic-gate ungetchar(c); 2450Sstevel@tonic-gate else if (c=='"') 2460Sstevel@tonic-gate comment(); 2470Sstevel@tonic-gate } 2480Sstevel@tonic-gate 249*802Scf46844 int 250*802Scf46844 iswhite(int c) 2510Sstevel@tonic-gate { 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate return (c == ' ' || c == '\t'); 2540Sstevel@tonic-gate } 2550Sstevel@tonic-gate 256*802Scf46844 int 257*802Scf46844 junk(wchar_t c) 2580Sstevel@tonic-gate { 2590Sstevel@tonic-gate 2600Sstevel@tonic-gate if (c && !value(vi_BEAUTIFY)) 2610Sstevel@tonic-gate return (0); 2620Sstevel@tonic-gate if (c >= ' ' && c != DELETE) 2630Sstevel@tonic-gate return (0); 2640Sstevel@tonic-gate switch (c) { 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate case '\t': 2670Sstevel@tonic-gate case '\n': 2680Sstevel@tonic-gate case '\f': 2690Sstevel@tonic-gate return (0); 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate default: 2720Sstevel@tonic-gate return (1); 2730Sstevel@tonic-gate } 2740Sstevel@tonic-gate } 2750Sstevel@tonic-gate 276*802Scf46844 void 277*802Scf46844 killed(void) 2780Sstevel@tonic-gate { 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate killcnt(addr2 - addr1 + 1); 2810Sstevel@tonic-gate } 2820Sstevel@tonic-gate 283*802Scf46844 void 284*802Scf46844 killcnt(int cnt) 2850Sstevel@tonic-gate { 2860Sstevel@tonic-gate extern char *verbalize(); 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate if (inopen) { 2890Sstevel@tonic-gate notecnt = cnt; 2900Sstevel@tonic-gate notenam = notesgn = (unsigned char *)""; 2910Sstevel@tonic-gate return; 2920Sstevel@tonic-gate } 2930Sstevel@tonic-gate if (!notable(cnt)) 2940Sstevel@tonic-gate return; 2950Sstevel@tonic-gate if (value(vi_TERSE) == 0) { 2960Sstevel@tonic-gate verbalize(cnt, Command, ""); 2970Sstevel@tonic-gate } else { 2980Sstevel@tonic-gate if (cnt == 1) { 299*802Scf46844 viprintf(gettext("1 line"), cnt); 3000Sstevel@tonic-gate } else { 301*802Scf46844 viprintf(gettext("%d lines"), cnt); 3020Sstevel@tonic-gate } 3030Sstevel@tonic-gate } 3040Sstevel@tonic-gate putNFL(); 3050Sstevel@tonic-gate } 3060Sstevel@tonic-gate 307*802Scf46844 int 308*802Scf46844 lineno(line *a) 3090Sstevel@tonic-gate { 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate return (a - zero); 3120Sstevel@tonic-gate } 3130Sstevel@tonic-gate 314*802Scf46844 int 315*802Scf46844 lineDOL(void) 3160Sstevel@tonic-gate { 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate return (lineno(dol)); 3190Sstevel@tonic-gate } 3200Sstevel@tonic-gate 321*802Scf46844 int 322*802Scf46844 lineDOT(void) 3230Sstevel@tonic-gate { 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate return (lineno(dot)); 3260Sstevel@tonic-gate } 3270Sstevel@tonic-gate 328*802Scf46844 void 329*802Scf46844 markDOT(void) 3300Sstevel@tonic-gate { 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate markpr(dot); 3330Sstevel@tonic-gate } 3340Sstevel@tonic-gate 335*802Scf46844 void 336*802Scf46844 markpr(line *which) 3370Sstevel@tonic-gate { 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate if ((inglobal == 0 || inopen) && which <= endcore) { 3400Sstevel@tonic-gate names['z'-'a'+1] = *which & ~01; 3410Sstevel@tonic-gate if (inopen) 3420Sstevel@tonic-gate ncols['z'-'a'+1] = cursor; 3430Sstevel@tonic-gate } 3440Sstevel@tonic-gate } 3450Sstevel@tonic-gate 346*802Scf46844 int 347*802Scf46844 markreg(int c) 3480Sstevel@tonic-gate { 3490Sstevel@tonic-gate 3500Sstevel@tonic-gate if (c == '\'' || c == '`') 3510Sstevel@tonic-gate return ('z' + 1); 3520Sstevel@tonic-gate if (c >= 'a' && c <= 'z') 3530Sstevel@tonic-gate return (c); 3540Sstevel@tonic-gate return (0); 3550Sstevel@tonic-gate } 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate /* 3580Sstevel@tonic-gate * Mesg decodes the terse/verbose strings. Thus 3590Sstevel@tonic-gate * 'xxx@yyy' -> 'xxx' if terse, else 'xxx yyy' 3600Sstevel@tonic-gate * 'xxx|yyy' -> 'xxx' if terse, else 'yyy' 3610Sstevel@tonic-gate * All others map to themselves. 3620Sstevel@tonic-gate */ 3630Sstevel@tonic-gate /* 3640Sstevel@tonic-gate * The feature described above was disabled for localizable messaging. 3650Sstevel@tonic-gate */ 3660Sstevel@tonic-gate unsigned char * 3670Sstevel@tonic-gate mesg(str) 368*802Scf46844 unsigned char *str; 3690Sstevel@tonic-gate { 370*802Scf46844 unsigned char *cp; 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate str = (unsigned char *)strcpy(genbuf, str); 3730Sstevel@tonic-gate /* commented out for localizable messaging */ 3740Sstevel@tonic-gate /* for (cp = str; *cp; cp++) 3750Sstevel@tonic-gate switch (*cp) { 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate case '@': 3780Sstevel@tonic-gate if (value(vi_TERSE)) 3790Sstevel@tonic-gate *cp = 0; 3800Sstevel@tonic-gate else 3810Sstevel@tonic-gate *cp = ' '; 3820Sstevel@tonic-gate break; 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate case '|': 3850Sstevel@tonic-gate if (value(vi_TERSE) == 0) 3860Sstevel@tonic-gate return (cp + 1); 3870Sstevel@tonic-gate *cp = 0; 3880Sstevel@tonic-gate break; 3890Sstevel@tonic-gate } */ 3900Sstevel@tonic-gate return (str); 3910Sstevel@tonic-gate } 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate /*VARARGS2*/ 394*802Scf46844 void 395*802Scf46844 merror(unsigned char *seekpt, int i) 3960Sstevel@tonic-gate { 397*802Scf46844 unsigned char *cp = linebuf; 3980Sstevel@tonic-gate 3990Sstevel@tonic-gate if (seekpt == 0) 4000Sstevel@tonic-gate return; 4010Sstevel@tonic-gate merror1(seekpt); 4020Sstevel@tonic-gate if (*cp == '\n') 4030Sstevel@tonic-gate putnl(), cp++; 4040Sstevel@tonic-gate if (inopen > 0 && clr_eol) 4050Sstevel@tonic-gate vclreol(); 4060Sstevel@tonic-gate if (enter_standout_mode && exit_bold) 407*802Scf46844 putpad((unsigned char *)enter_standout_mode); 4080Sstevel@tonic-gate #ifdef PRESUNEUC 409*802Scf46844 viprintf(mesg(cp), i); 4100Sstevel@tonic-gate #else 411*802Scf46844 viprintf((char *)mesg(cp), i); 4120Sstevel@tonic-gate #endif /* PRESUNEUC */ 4130Sstevel@tonic-gate if (enter_standout_mode && exit_bold) 414*802Scf46844 putpad((unsigned char *)exit_bold); 4150Sstevel@tonic-gate } 4160Sstevel@tonic-gate 417*802Scf46844 void 418*802Scf46844 merror1(unsigned char *seekpt) 4190Sstevel@tonic-gate { 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate strcpy(linebuf, seekpt); 4220Sstevel@tonic-gate } 4230Sstevel@tonic-gate 4240Sstevel@tonic-gate #define MAXDATA (56*1024) 425*802Scf46844 int 426*802Scf46844 morelines(void) 4270Sstevel@tonic-gate { 428*802Scf46844 unsigned char *end; 4290Sstevel@tonic-gate 4300Sstevel@tonic-gate if ((int) sbrk(1024 * sizeof (line)) == -1) { 4310Sstevel@tonic-gate if (endcore >= (line *) MAXDATA) 4320Sstevel@tonic-gate return -1; 4330Sstevel@tonic-gate end = (unsigned char *) MAXDATA; 4340Sstevel@tonic-gate /* 4350Sstevel@tonic-gate * Ask for end+2 sice we want end to be the last used location. 4360Sstevel@tonic-gate */ 4370Sstevel@tonic-gate while (brk(end+2) == -1) 4380Sstevel@tonic-gate end -= 64; 4390Sstevel@tonic-gate if (end <= (unsigned char *) endcore) 4400Sstevel@tonic-gate return -1; 4410Sstevel@tonic-gate endcore = (line *) end; 4420Sstevel@tonic-gate } else { 4430Sstevel@tonic-gate endcore += 1024; 4440Sstevel@tonic-gate } 4450Sstevel@tonic-gate return (0); 4460Sstevel@tonic-gate } 4470Sstevel@tonic-gate 448*802Scf46844 void 449*802Scf46844 nonzero(void) 4500Sstevel@tonic-gate { 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate if (addr1 == zero) { 4530Sstevel@tonic-gate notempty(); 4540Sstevel@tonic-gate error(value(vi_TERSE) ? gettext("Nonzero address required") : 4550Sstevel@tonic-gate gettext("Nonzero address required on this command")); 4560Sstevel@tonic-gate } 4570Sstevel@tonic-gate } 4580Sstevel@tonic-gate 459*802Scf46844 int 460*802Scf46844 notable(int i) 4610Sstevel@tonic-gate { 4620Sstevel@tonic-gate 4630Sstevel@tonic-gate return (hush == 0 && !inglobal && i > value(vi_REPORT)); 4640Sstevel@tonic-gate } 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate 467*802Scf46844 void 468*802Scf46844 notempty(void) 4690Sstevel@tonic-gate { 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate if (dol == zero) 4720Sstevel@tonic-gate error(value(vi_TERSE) ? gettext("No lines") : 4730Sstevel@tonic-gate gettext("No lines in the buffer")); 4740Sstevel@tonic-gate } 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate 477*802Scf46844 void 478*802Scf46844 netchHAD(int cnt) 4790Sstevel@tonic-gate { 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate netchange(lineDOL() - cnt); 4820Sstevel@tonic-gate } 4830Sstevel@tonic-gate 484*802Scf46844 void 485*802Scf46844 netchange(int i) 4860Sstevel@tonic-gate { 487*802Scf46844 unsigned char *cp; 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate if (i > 0) 4900Sstevel@tonic-gate notesgn = cp = (unsigned char *)"more "; 4910Sstevel@tonic-gate else 4920Sstevel@tonic-gate notesgn = cp = (unsigned char *)"fewer ", i = -i; 4930Sstevel@tonic-gate if (inopen) { 4940Sstevel@tonic-gate notecnt = i; 4950Sstevel@tonic-gate notenam = (unsigned char *)""; 4960Sstevel@tonic-gate return; 4970Sstevel@tonic-gate } 4980Sstevel@tonic-gate if (!notable(i)) 4990Sstevel@tonic-gate return; 5000Sstevel@tonic-gate if (*cp == 'm') /* for ease of messge localization */ 5010Sstevel@tonic-gate #ifdef PRESUNEUC 502*802Scf46844 viprintf(mesg(value(vi_TERSE) ? 5030Sstevel@tonic-gate #else 504*802Scf46844 viprintf((char *)mesg(value(vi_TERSE) ? 5050Sstevel@tonic-gate #endif /* PRESUNEUC */ 5060Sstevel@tonic-gate gettext("%d more lines") : 5070Sstevel@tonic-gate /* 5080Sstevel@tonic-gate * TRANSLATION_NOTE 5090Sstevel@tonic-gate * Reference order of arguments must not 5100Sstevel@tonic-gate * be changed using '%digit$', since vi's 511*802Scf46844 * viprintf() does not support it. 5120Sstevel@tonic-gate */ 5130Sstevel@tonic-gate gettext("%d more lines in file after %s")), i, Command); 5140Sstevel@tonic-gate else 5150Sstevel@tonic-gate #ifdef PRESUNEUC 516*802Scf46844 viprintf(mesg(value(vi_TERSE) ? 5170Sstevel@tonic-gate #else 518*802Scf46844 viprintf((char *)mesg(value(vi_TERSE) ? 5190Sstevel@tonic-gate #endif /* PRESUNEUC */ 5200Sstevel@tonic-gate gettext("%d fewer lines") : 5210Sstevel@tonic-gate /* 5220Sstevel@tonic-gate * TRANSLATION_NOTE 5230Sstevel@tonic-gate * Reference order of arguments must not 5240Sstevel@tonic-gate * be changed using '%digit$', since vi's 525*802Scf46844 * viprintf() does not support it. 5260Sstevel@tonic-gate */ 5270Sstevel@tonic-gate gettext("%d fewer lines in file after %s")), i, Command); 5280Sstevel@tonic-gate putNFL(); 5290Sstevel@tonic-gate } 5300Sstevel@tonic-gate 531*802Scf46844 void 532*802Scf46844 putmark(line *addr) 5330Sstevel@tonic-gate { 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate putmk1(addr, putline()); 5360Sstevel@tonic-gate } 5370Sstevel@tonic-gate 538*802Scf46844 void 539*802Scf46844 putmk1(line *addr, int n) 5400Sstevel@tonic-gate { 541*802Scf46844 line *markp; 542*802Scf46844 int oldglobmk; 5430Sstevel@tonic-gate 5440Sstevel@tonic-gate oldglobmk = *addr & 1; 5450Sstevel@tonic-gate *addr &= ~1; 5460Sstevel@tonic-gate for (markp = (anymarks ? names : &names['z'-'a'+1]); 5470Sstevel@tonic-gate markp <= &names['z'-'a'+1]; markp++) 5480Sstevel@tonic-gate if (*markp == *addr) 5490Sstevel@tonic-gate *markp = n; 5500Sstevel@tonic-gate *addr = n | oldglobmk; 5510Sstevel@tonic-gate } 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate unsigned char * 5540Sstevel@tonic-gate plural(i) 5550Sstevel@tonic-gate long i; 5560Sstevel@tonic-gate { 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate return (i == 1 ? (unsigned char *)"" : (unsigned char *)"s"); 5590Sstevel@tonic-gate } 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate int qcount(); 5620Sstevel@tonic-gate short vcntcol; 5630Sstevel@tonic-gate 564*802Scf46844 int 565*802Scf46844 qcolumn(unsigned char *lim, unsigned char *gp) 5660Sstevel@tonic-gate { 567*802Scf46844 int x, length; 5680Sstevel@tonic-gate int col; 5690Sstevel@tonic-gate wchar_t wchar; 5700Sstevel@tonic-gate int (*OO)(); 5710Sstevel@tonic-gate 5720Sstevel@tonic-gate OO = Outchar; 5730Sstevel@tonic-gate Outchar = qcount; 5740Sstevel@tonic-gate vcntcol = 0; 5750Sstevel@tonic-gate if (lim != NULL) { 5760Sstevel@tonic-gate if(lim == linebuf - 1 || lim == &linebuf[LBSIZE-2]) 5770Sstevel@tonic-gate length = 1; 5780Sstevel@tonic-gate else 5790Sstevel@tonic-gate length = mbtowc(&wchar, (char *)lim, MULTI_BYTE_MAX); 5800Sstevel@tonic-gate if(length < 0) 5810Sstevel@tonic-gate length = 1; 5820Sstevel@tonic-gate x = lim[length]; 5830Sstevel@tonic-gate lim[length] = 0; 5840Sstevel@tonic-gate } 5850Sstevel@tonic-gate pline(0); 5860Sstevel@tonic-gate if (lim != NULL) 5870Sstevel@tonic-gate lim[length] = x; 5880Sstevel@tonic-gate if(length > 1 && !gp) { 5890Sstevel@tonic-gate /* put cursor at beginning of multibyte character */ 5900Sstevel@tonic-gate if ((col = wcwidth(wchar)) < 0) 5910Sstevel@tonic-gate col = 0; 5920Sstevel@tonic-gate vcntcol = vcntcol - col + 1; 5930Sstevel@tonic-gate } 5940Sstevel@tonic-gate if (gp) 5950Sstevel@tonic-gate while (*gp) { 5960Sstevel@tonic-gate length = mbtowc(&wchar, (char *)gp, MULTI_BYTE_MAX); 5970Sstevel@tonic-gate if(length < 0) { 5980Sstevel@tonic-gate putoctal = 1; 5990Sstevel@tonic-gate putchar(*gp++); 6000Sstevel@tonic-gate putoctal = 0; 6010Sstevel@tonic-gate } else { 6020Sstevel@tonic-gate putchar(wchar); 6030Sstevel@tonic-gate gp += length; 6040Sstevel@tonic-gate } 6050Sstevel@tonic-gate } 6060Sstevel@tonic-gate Outchar = OO; 6070Sstevel@tonic-gate return (vcntcol); 6080Sstevel@tonic-gate } 6090Sstevel@tonic-gate 6100Sstevel@tonic-gate /* This routine puts cursor after multibyte character */ 611*802Scf46844 int 612*802Scf46844 nqcolumn(unsigned char *lim, unsigned char *gp) 6130Sstevel@tonic-gate { 614*802Scf46844 int x, length; 6150Sstevel@tonic-gate wchar_t wchar; 6160Sstevel@tonic-gate int (*OO)(); 6170Sstevel@tonic-gate 6180Sstevel@tonic-gate OO = Outchar; 6190Sstevel@tonic-gate Outchar = qcount; 6200Sstevel@tonic-gate vcntcol = 0; 6210Sstevel@tonic-gate if (lim != NULL) { 6220Sstevel@tonic-gate if(lim == linebuf - 1 || lim == &linebuf[LBSIZE-2]) 6230Sstevel@tonic-gate length = 1; 6240Sstevel@tonic-gate else 6250Sstevel@tonic-gate length = mbtowc(&wchar, (char *)lim, MULTI_BYTE_MAX); 6260Sstevel@tonic-gate if(length < 0) 6270Sstevel@tonic-gate length = 1; 6280Sstevel@tonic-gate x = lim[length]; 6290Sstevel@tonic-gate lim[length] = 0; 6300Sstevel@tonic-gate } 6310Sstevel@tonic-gate pline(0); 6320Sstevel@tonic-gate if (lim != NULL) 6330Sstevel@tonic-gate lim[length] = x; 6340Sstevel@tonic-gate if (gp) 6350Sstevel@tonic-gate while (*gp) { 6360Sstevel@tonic-gate length = mbtowc(&wchar, (char *)gp, MULTI_BYTE_MAX); 6370Sstevel@tonic-gate if(length < 0) { 6380Sstevel@tonic-gate putoctal = 1; 6390Sstevel@tonic-gate putchar(*gp++); 6400Sstevel@tonic-gate putoctal = 0; 6410Sstevel@tonic-gate } else { 6420Sstevel@tonic-gate putchar(wchar); 6430Sstevel@tonic-gate gp += length; 6440Sstevel@tonic-gate } 6450Sstevel@tonic-gate } 6460Sstevel@tonic-gate Outchar = OO; 6470Sstevel@tonic-gate return (vcntcol); 6480Sstevel@tonic-gate } 6490Sstevel@tonic-gate 6500Sstevel@tonic-gate int 6510Sstevel@tonic-gate qcount(c) 6520Sstevel@tonic-gate wchar_t c; 6530Sstevel@tonic-gate { 654*802Scf46844 int cols; 6550Sstevel@tonic-gate #ifndef PRESUNEUC 656*802Scf46844 int remcols; 657*802Scf46844 short OWCOLS; 6580Sstevel@tonic-gate #endif /* PRESUNEUC */ 6590Sstevel@tonic-gate 6600Sstevel@tonic-gate if (c == '\t') { 6610Sstevel@tonic-gate vcntcol += value(vi_TABSTOP) - vcntcol % value(vi_TABSTOP); 662*802Scf46844 return (0); 6630Sstevel@tonic-gate } 6640Sstevel@tonic-gate #ifdef PRESUNEUC 6650Sstevel@tonic-gate if ((cols = wcwidth(c)) > 0) 6660Sstevel@tonic-gate vcntcol += cols; 6670Sstevel@tonic-gate #else 6680Sstevel@tonic-gate if ((cols = wcwidth(c)) < 0) 6690Sstevel@tonic-gate cols = 0; 6700Sstevel@tonic-gate OWCOLS = WCOLS; 6710Sstevel@tonic-gate if (WCOLS == 0) 6720Sstevel@tonic-gate WCOLS = columns; 6730Sstevel@tonic-gate if ((mc_wrap) == 1 && (remcols = (WCOLS - (vcntcol % WCOLS))) < cols) 6740Sstevel@tonic-gate vcntcol += remcols; 6750Sstevel@tonic-gate WCOLS = OWCOLS; 6760Sstevel@tonic-gate vcntcol += cols; 6770Sstevel@tonic-gate #endif /* PRESUNEUC */ 678*802Scf46844 return (0); 6790Sstevel@tonic-gate } 6800Sstevel@tonic-gate 681*802Scf46844 void 682*802Scf46844 reverse(line *a1, line *a2) 6830Sstevel@tonic-gate { 684*802Scf46844 line t; 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate for (;;) { 6870Sstevel@tonic-gate t = *--a2; 6880Sstevel@tonic-gate if (a2 <= a1) 6890Sstevel@tonic-gate return; 6900Sstevel@tonic-gate *a2 = *a1; 6910Sstevel@tonic-gate *a1++ = t; 6920Sstevel@tonic-gate } 6930Sstevel@tonic-gate } 6940Sstevel@tonic-gate 695*802Scf46844 void 696*802Scf46844 save(line *a1, line *a2) 6970Sstevel@tonic-gate { 698*802Scf46844 int more; 6990Sstevel@tonic-gate 7000Sstevel@tonic-gate if (!FIXUNDO) 7010Sstevel@tonic-gate return; 7020Sstevel@tonic-gate #ifdef UNDOTRACE 7030Sstevel@tonic-gate if (trace) 7040Sstevel@tonic-gate vudump("before save"); 7050Sstevel@tonic-gate #endif 7060Sstevel@tonic-gate undkind = UNDNONE; 7070Sstevel@tonic-gate undadot = dot; 7080Sstevel@tonic-gate more = (a2 - a1 + 1) - (unddol - dol); 7090Sstevel@tonic-gate while (more > (endcore - truedol)) 7100Sstevel@tonic-gate if (morelines() < 0) 7110Sstevel@tonic-gate error(value(vi_TERSE) ? gettext("Out of memory") : 7120Sstevel@tonic-gate gettext("Out of memory saving lines for undo - try using ed")); 7130Sstevel@tonic-gate if (more) 7140Sstevel@tonic-gate (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1, 7150Sstevel@tonic-gate (truedol - unddol)); 7160Sstevel@tonic-gate unddol += more; 7170Sstevel@tonic-gate truedol += more; 7180Sstevel@tonic-gate copyw(dol + 1, a1, a2 - a1 + 1); 7190Sstevel@tonic-gate undkind = UNDALL; 7200Sstevel@tonic-gate unddel = a1 - 1; 7210Sstevel@tonic-gate undap1 = a1; 7220Sstevel@tonic-gate undap2 = a2 + 1; 7230Sstevel@tonic-gate #ifdef UNDOTRACE 7240Sstevel@tonic-gate if (trace) 7250Sstevel@tonic-gate vudump("after save"); 7260Sstevel@tonic-gate #endif 7270Sstevel@tonic-gate } 7280Sstevel@tonic-gate 729*802Scf46844 void 730*802Scf46844 save12(void) 7310Sstevel@tonic-gate { 7320Sstevel@tonic-gate 7330Sstevel@tonic-gate save(addr1, addr2); 7340Sstevel@tonic-gate } 7350Sstevel@tonic-gate 736*802Scf46844 void 737*802Scf46844 saveall(void) 7380Sstevel@tonic-gate { 7390Sstevel@tonic-gate 7400Sstevel@tonic-gate save(one, dol); 7410Sstevel@tonic-gate } 7420Sstevel@tonic-gate 743*802Scf46844 int 744*802Scf46844 span(void) 7450Sstevel@tonic-gate { 7460Sstevel@tonic-gate 7470Sstevel@tonic-gate return (addr2 - addr1 + 1); 7480Sstevel@tonic-gate } 7490Sstevel@tonic-gate 750*802Scf46844 void 751*802Scf46844 sync(void) 7520Sstevel@tonic-gate { 7530Sstevel@tonic-gate 7540Sstevel@tonic-gate chng = 0; 7550Sstevel@tonic-gate tchng = 0; 7560Sstevel@tonic-gate xchng = 0; 7570Sstevel@tonic-gate } 7580Sstevel@tonic-gate 7590Sstevel@tonic-gate 760*802Scf46844 int 761*802Scf46844 skipwh(void) 7620Sstevel@tonic-gate { 763*802Scf46844 int wh; 7640Sstevel@tonic-gate 7650Sstevel@tonic-gate wh = 0; 7660Sstevel@tonic-gate while (iswhite(peekchar())) { 7670Sstevel@tonic-gate wh++; 7680Sstevel@tonic-gate ignchar(); 7690Sstevel@tonic-gate } 7700Sstevel@tonic-gate return (wh); 7710Sstevel@tonic-gate } 7720Sstevel@tonic-gate 7730Sstevel@tonic-gate /*VARARGS2*/ 774*802Scf46844 void 775*802Scf46844 smerror(unsigned char *seekpt, unsigned char *cp) 7760Sstevel@tonic-gate { 7770Sstevel@tonic-gate 7780Sstevel@tonic-gate errcnt++; 7790Sstevel@tonic-gate merror1(seekpt); 7800Sstevel@tonic-gate if (inopen && clr_eol) 7810Sstevel@tonic-gate vclreol(); 7820Sstevel@tonic-gate if (enter_standout_mode && exit_bold) 783*802Scf46844 putpad((unsigned char *)enter_standout_mode); 7840Sstevel@tonic-gate lprintf(mesg(linebuf), cp); 7850Sstevel@tonic-gate if (enter_standout_mode && exit_bold) 786*802Scf46844 putpad((unsigned char *)exit_bold); 7870Sstevel@tonic-gate } 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate unsigned char * 7900Sstevel@tonic-gate strend(cp) 791*802Scf46844 unsigned char *cp; 7920Sstevel@tonic-gate { 7930Sstevel@tonic-gate 7940Sstevel@tonic-gate while (*cp) 7950Sstevel@tonic-gate cp++; 7960Sstevel@tonic-gate return (cp); 7970Sstevel@tonic-gate } 7980Sstevel@tonic-gate 799*802Scf46844 void 800*802Scf46844 strcLIN(unsigned char *dp) 8010Sstevel@tonic-gate { 8020Sstevel@tonic-gate 8030Sstevel@tonic-gate CP(linebuf, dp); 8040Sstevel@tonic-gate } 8050Sstevel@tonic-gate 8060Sstevel@tonic-gate /* 8070Sstevel@tonic-gate * A system error has occurred that we need to perror. 8080Sstevel@tonic-gate * danger is true if we are unsure of the contents of 8090Sstevel@tonic-gate * the file or our buffer, e.g. a write error in the 8100Sstevel@tonic-gate * middle of a write operation, or a temp file error. 8110Sstevel@tonic-gate */ 812*802Scf46844 void 813*802Scf46844 syserror(int danger) 8140Sstevel@tonic-gate { 815*802Scf46844 int e = errno; 8160Sstevel@tonic-gate char *errstr; 8170Sstevel@tonic-gate extern char *strerror(); 8180Sstevel@tonic-gate 8190Sstevel@tonic-gate dirtcnt = 0; 8200Sstevel@tonic-gate putchar(' '); 8210Sstevel@tonic-gate if (danger) 8220Sstevel@tonic-gate edited = 0; /* for temp file errors, for example */ 8230Sstevel@tonic-gate if ((errstr = strerror(e)) != NULL) 8240Sstevel@tonic-gate error(errstr); 8250Sstevel@tonic-gate else 8260Sstevel@tonic-gate error(gettext("System error %d"), e); 8270Sstevel@tonic-gate } 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate /* 8300Sstevel@tonic-gate * Return the column number that results from being in column col and 8310Sstevel@tonic-gate * hitting a tab, where tabs are set every ts columns. Work right for 8320Sstevel@tonic-gate * the case where col > columns, even if ts does not divide columns. 8330Sstevel@tonic-gate */ 834*802Scf46844 int 835*802Scf46844 tabcol(int col, int ts) 8360Sstevel@tonic-gate { 8370Sstevel@tonic-gate int offset, result; 8380Sstevel@tonic-gate 8390Sstevel@tonic-gate if (col >= columns) { 8400Sstevel@tonic-gate offset = columns * (col/columns); 8410Sstevel@tonic-gate col -= offset; 8420Sstevel@tonic-gate } else 8430Sstevel@tonic-gate offset = 0; 8440Sstevel@tonic-gate result = col + ts - (col % ts) + offset; 8450Sstevel@tonic-gate return (result); 8460Sstevel@tonic-gate } 8470Sstevel@tonic-gate 8480Sstevel@tonic-gate unsigned char * 8490Sstevel@tonic-gate vfindcol(i) 8500Sstevel@tonic-gate int i; 8510Sstevel@tonic-gate { 852*802Scf46844 unsigned char *cp, *oldcp; 853*802Scf46844 int (*OO)() = Outchar; 854*802Scf46844 int length; 8550Sstevel@tonic-gate unsigned char x; 8560Sstevel@tonic-gate wchar_t wchar; 8570Sstevel@tonic-gate 8580Sstevel@tonic-gate Outchar = qcount; 859*802Scf46844 (void) qcolumn(linebuf - 1, (unsigned char *)NOSTR); 8600Sstevel@tonic-gate for (cp = linebuf; *cp && vcntcol < i; ) { 8610Sstevel@tonic-gate oldcp = cp; 8620Sstevel@tonic-gate length = mbtowc(&wchar, (char *)cp, MULTI_BYTE_MAX); 8630Sstevel@tonic-gate if(length < 0) { 8640Sstevel@tonic-gate putoctal = 1; 8650Sstevel@tonic-gate putchar(*cp++); 8660Sstevel@tonic-gate putoctal = 0; 8670Sstevel@tonic-gate } else { 8680Sstevel@tonic-gate putchar(wchar); 8690Sstevel@tonic-gate cp += length; 8700Sstevel@tonic-gate } 8710Sstevel@tonic-gate } 8720Sstevel@tonic-gate if (cp != linebuf) 8730Sstevel@tonic-gate cp = oldcp; 8740Sstevel@tonic-gate Outchar = OO; 8750Sstevel@tonic-gate return (cp); 8760Sstevel@tonic-gate } 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate unsigned char * 8790Sstevel@tonic-gate vskipwh(cp) 880*802Scf46844 unsigned char *cp; 8810Sstevel@tonic-gate { 8820Sstevel@tonic-gate 8830Sstevel@tonic-gate while (iswhite(*cp) && cp[1]) 8840Sstevel@tonic-gate cp++; 8850Sstevel@tonic-gate return (cp); 8860Sstevel@tonic-gate } 8870Sstevel@tonic-gate 8880Sstevel@tonic-gate 8890Sstevel@tonic-gate unsigned char * 8900Sstevel@tonic-gate vpastwh(cp) 891*802Scf46844 unsigned char *cp; 8920Sstevel@tonic-gate { 8930Sstevel@tonic-gate 8940Sstevel@tonic-gate while (iswhite(*cp)) 8950Sstevel@tonic-gate cp++; 8960Sstevel@tonic-gate return (cp); 8970Sstevel@tonic-gate } 8980Sstevel@tonic-gate 899*802Scf46844 int 900*802Scf46844 whitecnt(unsigned char *cp) 9010Sstevel@tonic-gate { 902*802Scf46844 int i; 9030Sstevel@tonic-gate 9040Sstevel@tonic-gate i = 0; 9050Sstevel@tonic-gate for (;;) 9060Sstevel@tonic-gate switch (*cp++) { 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate case '\t': 9090Sstevel@tonic-gate i += value(vi_TABSTOP) - i % value(vi_TABSTOP); 9100Sstevel@tonic-gate break; 9110Sstevel@tonic-gate 9120Sstevel@tonic-gate case ' ': 9130Sstevel@tonic-gate i++; 9140Sstevel@tonic-gate break; 9150Sstevel@tonic-gate 9160Sstevel@tonic-gate default: 9170Sstevel@tonic-gate return (i); 9180Sstevel@tonic-gate } 9190Sstevel@tonic-gate } 9200Sstevel@tonic-gate 921*802Scf46844 void 922*802Scf46844 markit(line *addr) 9230Sstevel@tonic-gate { 9240Sstevel@tonic-gate 9250Sstevel@tonic-gate if (addr != dot && addr >= one && addr <= dol) 9260Sstevel@tonic-gate markDOT(); 9270Sstevel@tonic-gate } 9280Sstevel@tonic-gate 9290Sstevel@tonic-gate /* 9300Sstevel@tonic-gate * The following code is defensive programming against a bug in the 9310Sstevel@tonic-gate * pdp-11 overlay implementation. Sometimes it goes nuts and asks 9320Sstevel@tonic-gate * for an overlay with some garbage number, which generates an emt 9330Sstevel@tonic-gate * trap. This is a less than elegant solution, but it is somewhat 9340Sstevel@tonic-gate * better than core dumping and losing your work, leaving your tty 9350Sstevel@tonic-gate * in a weird state, etc. 9360Sstevel@tonic-gate */ 9370Sstevel@tonic-gate int _ovno; 9380Sstevel@tonic-gate 9390Sstevel@tonic-gate /*ARGSUSED*/ 9400Sstevel@tonic-gate void 9410Sstevel@tonic-gate onemt(sig) 9420Sstevel@tonic-gate int sig; 9430Sstevel@tonic-gate { 9440Sstevel@tonic-gate int oovno; 9450Sstevel@tonic-gate 9460Sstevel@tonic-gate signal(SIGEMT, onemt); 9470Sstevel@tonic-gate oovno = _ovno; 9480Sstevel@tonic-gate /* 2 and 3 are valid on 11/40 type vi, so */ 9490Sstevel@tonic-gate if (_ovno < 0 || _ovno > 3) 9500Sstevel@tonic-gate _ovno = 0; 9510Sstevel@tonic-gate error(value(vi_TERSE) ? gettext("emt trap, _ovno is %d ") : 9520Sstevel@tonic-gate gettext("emt trap, _ovno is %d - try again")); 9530Sstevel@tonic-gate } 9540Sstevel@tonic-gate 9550Sstevel@tonic-gate /* 9560Sstevel@tonic-gate * When a hangup occurs our actions are similar to a preserve 9570Sstevel@tonic-gate * command. If the buffer has not been [Modified], then we do 9580Sstevel@tonic-gate * nothing but remove the temporary files and exit. 9590Sstevel@tonic-gate * Otherwise, we sync the temp file and then attempt a preserve. 9600Sstevel@tonic-gate * If the preserve succeeds, we unlink our temp files. 9610Sstevel@tonic-gate * If the preserve fails, we leave the temp files as they are 9620Sstevel@tonic-gate * as they are a backup even without preservation if they 9630Sstevel@tonic-gate * are not removed. 9640Sstevel@tonic-gate */ 9650Sstevel@tonic-gate 9660Sstevel@tonic-gate /*ARGSUSED*/ 9670Sstevel@tonic-gate void 9680Sstevel@tonic-gate onhup(sig) 9690Sstevel@tonic-gate int sig; 9700Sstevel@tonic-gate { 9710Sstevel@tonic-gate 9720Sstevel@tonic-gate /* 9730Sstevel@tonic-gate * USG tty driver can send multiple HUP's!! 9740Sstevel@tonic-gate */ 9750Sstevel@tonic-gate signal(SIGINT, SIG_IGN); 9760Sstevel@tonic-gate signal(SIGHUP, SIG_IGN); 9770Sstevel@tonic-gate if (chng == 0) { 9780Sstevel@tonic-gate cleanup(1); 9790Sstevel@tonic-gate exit(++errcnt); 9800Sstevel@tonic-gate } 9810Sstevel@tonic-gate if (setexit() == 0) { 9820Sstevel@tonic-gate if (preserve()) { 9830Sstevel@tonic-gate cleanup(1); 9840Sstevel@tonic-gate exit(++errcnt); 9850Sstevel@tonic-gate } 9860Sstevel@tonic-gate } 9870Sstevel@tonic-gate if (kflag) 9880Sstevel@tonic-gate crypt_close(perm); 9890Sstevel@tonic-gate if (xtflag) 9900Sstevel@tonic-gate crypt_close(tperm); 9910Sstevel@tonic-gate exit(++errcnt); 9920Sstevel@tonic-gate } 9930Sstevel@tonic-gate 9940Sstevel@tonic-gate /* 9950Sstevel@tonic-gate * Similar to onhup. This happens when any random core dump occurs, 9960Sstevel@tonic-gate * e.g. a bug in vi. We preserve the file and then generate a core. 9970Sstevel@tonic-gate */ 9980Sstevel@tonic-gate void oncore(sig) 9990Sstevel@tonic-gate int sig; 10000Sstevel@tonic-gate { 10010Sstevel@tonic-gate static int timescalled = 0; 10020Sstevel@tonic-gate char *messagep; /* for message localization */ 10030Sstevel@tonic-gate 10040Sstevel@tonic-gate /* 10050Sstevel@tonic-gate * USG tty driver can send multiple HUP's!! 10060Sstevel@tonic-gate */ 10070Sstevel@tonic-gate signal(SIGINT, SIG_IGN); 10080Sstevel@tonic-gate signal(SIGHUP, SIG_IGN); 10090Sstevel@tonic-gate signal(sig, SIG_DFL); /* Insure that we don't catch it again */ 10100Sstevel@tonic-gate messagep = (char *)gettext("\r\nYour file has been preserved\r\n"); 10110Sstevel@tonic-gate if (timescalled++ == 0 && chng && setexit() == 0) { 10120Sstevel@tonic-gate if (inopen) 10130Sstevel@tonic-gate vsave(); 1014*802Scf46844 (void) preserve(); 10150Sstevel@tonic-gate write(1, messagep, strlen(messagep)); 10160Sstevel@tonic-gate } 10170Sstevel@tonic-gate if (timescalled < 2) { 10180Sstevel@tonic-gate normal(normf); 10190Sstevel@tonic-gate cleanup(2); 10200Sstevel@tonic-gate kill(getpid(), sig); /* Resend ourselves the same signal */ 10210Sstevel@tonic-gate /* We won't get past here */ 10220Sstevel@tonic-gate } 10230Sstevel@tonic-gate if (kflag) 10240Sstevel@tonic-gate crypt_close(perm); 10250Sstevel@tonic-gate if (xtflag) 10260Sstevel@tonic-gate crypt_close(tperm); 10270Sstevel@tonic-gate exit(++errcnt); 10280Sstevel@tonic-gate } 10290Sstevel@tonic-gate 10300Sstevel@tonic-gate /* 10310Sstevel@tonic-gate * An interrupt occurred. Drain any output which 10320Sstevel@tonic-gate * is still in the output buffering pipeline. 10330Sstevel@tonic-gate * Catch interrupts again. Unless we are in visual 10340Sstevel@tonic-gate * reset the output state (out of -nl mode, e.g). 10350Sstevel@tonic-gate * Then like a normal error (with the \n before Interrupt 10360Sstevel@tonic-gate * suppressed in visual mode). 10370Sstevel@tonic-gate */ 10380Sstevel@tonic-gate 10390Sstevel@tonic-gate /*ARGSUSED*/ 10400Sstevel@tonic-gate void 10410Sstevel@tonic-gate onintr(sig) 10420Sstevel@tonic-gate int sig; 10430Sstevel@tonic-gate { 10440Sstevel@tonic-gate #ifndef CBREAK 10450Sstevel@tonic-gate signal(SIGINT, onintr); 10460Sstevel@tonic-gate #else 10470Sstevel@tonic-gate signal(SIGINT, inopen ? vintr : onintr); 10480Sstevel@tonic-gate #endif 10490Sstevel@tonic-gate cancelalarm(); 10500Sstevel@tonic-gate draino(); 10510Sstevel@tonic-gate if (!inopen) { 10520Sstevel@tonic-gate pstop(); 10530Sstevel@tonic-gate setlastchar('\n'); 10540Sstevel@tonic-gate #ifdef CBREAK 10550Sstevel@tonic-gate } 10560Sstevel@tonic-gate #else 10570Sstevel@tonic-gate } else 10580Sstevel@tonic-gate vraw(); 10590Sstevel@tonic-gate #endif 10600Sstevel@tonic-gate error(gettext("\nInterrupt") + (inopen!=0)); 10610Sstevel@tonic-gate } 10620Sstevel@tonic-gate 10630Sstevel@tonic-gate /* 10640Sstevel@tonic-gate * If we are interruptible, enable interrupts again. 10650Sstevel@tonic-gate * In some critical sections we turn interrupts off, 10660Sstevel@tonic-gate * but not very often. 10670Sstevel@tonic-gate */ 1068*802Scf46844 void 1069*802Scf46844 setrupt(void) 10700Sstevel@tonic-gate { 10710Sstevel@tonic-gate 10720Sstevel@tonic-gate if (ruptible) { 10730Sstevel@tonic-gate #ifndef CBREAK 10740Sstevel@tonic-gate signal(SIGINT, onintr); 10750Sstevel@tonic-gate #else 10760Sstevel@tonic-gate signal(SIGINT, inopen ? vintr : onintr); 10770Sstevel@tonic-gate #endif 10780Sstevel@tonic-gate #ifdef SIGTSTP 10790Sstevel@tonic-gate if (dosusp) 10800Sstevel@tonic-gate signal(SIGTSTP, onsusp); 10810Sstevel@tonic-gate #endif 10820Sstevel@tonic-gate } 10830Sstevel@tonic-gate } 10840Sstevel@tonic-gate 1085*802Scf46844 int 1086*802Scf46844 preserve(void) 10870Sstevel@tonic-gate { 10880Sstevel@tonic-gate 10890Sstevel@tonic-gate #ifdef VMUNIX 10900Sstevel@tonic-gate tflush(); 10910Sstevel@tonic-gate #endif 10920Sstevel@tonic-gate synctmp(); 10930Sstevel@tonic-gate pid = fork(); 10940Sstevel@tonic-gate if (pid < 0) 10950Sstevel@tonic-gate return (0); 10960Sstevel@tonic-gate if (pid == 0) { 10970Sstevel@tonic-gate close(0); 10980Sstevel@tonic-gate dup(tfile); 10990Sstevel@tonic-gate execlp(EXPRESERVE, "expreserve", (char *) 0); 11000Sstevel@tonic-gate exit(++errcnt); 11010Sstevel@tonic-gate } 11020Sstevel@tonic-gate waitfor(); 11030Sstevel@tonic-gate if (rpid == pid && status == 0) 11040Sstevel@tonic-gate return (1); 11050Sstevel@tonic-gate return (0); 11060Sstevel@tonic-gate } 11070Sstevel@tonic-gate 11080Sstevel@tonic-gate #ifndef V6 11090Sstevel@tonic-gate void exit(i) 11100Sstevel@tonic-gate int i; 11110Sstevel@tonic-gate { 11120Sstevel@tonic-gate 1113*802Scf46844 extern void _exit(int) __NORETURN; 11140Sstevel@tonic-gate #ifdef TRACE 11150Sstevel@tonic-gate if (trace) 11160Sstevel@tonic-gate fclose(trace); 11170Sstevel@tonic-gate #endif 11180Sstevel@tonic-gate _exit(i); 11190Sstevel@tonic-gate } 11200Sstevel@tonic-gate #endif 11210Sstevel@tonic-gate 11220Sstevel@tonic-gate #ifdef SIGTSTP 11230Sstevel@tonic-gate /* 11240Sstevel@tonic-gate * We have just gotten a susp. Suspend and prepare to resume. 11250Sstevel@tonic-gate */ 11260Sstevel@tonic-gate extern void redraw(); 11270Sstevel@tonic-gate 11280Sstevel@tonic-gate /*ARGSUSED*/ 11290Sstevel@tonic-gate void 11300Sstevel@tonic-gate onsusp(sig) 11310Sstevel@tonic-gate int sig; 11320Sstevel@tonic-gate { 11330Sstevel@tonic-gate ttymode f; 11340Sstevel@tonic-gate int savenormtty; 11350Sstevel@tonic-gate 11360Sstevel@tonic-gate f = setty(normf); 11370Sstevel@tonic-gate vnfl(); 1138*802Scf46844 putpad((unsigned char *)exit_ca_mode); 11390Sstevel@tonic-gate flush(); 11400Sstevel@tonic-gate resetterm(); 11410Sstevel@tonic-gate savenormtty = normtty; 11420Sstevel@tonic-gate normtty = 0; 11430Sstevel@tonic-gate 11440Sstevel@tonic-gate signal(SIGTSTP, SIG_DFL); 11450Sstevel@tonic-gate kill(0, SIGTSTP); 11460Sstevel@tonic-gate 11470Sstevel@tonic-gate /* the pc stops here */ 11480Sstevel@tonic-gate 11490Sstevel@tonic-gate signal(SIGTSTP, onsusp); 11500Sstevel@tonic-gate normtty = savenormtty; 11510Sstevel@tonic-gate vcontin(0); 11520Sstevel@tonic-gate flush(); 11530Sstevel@tonic-gate setty(f); 11540Sstevel@tonic-gate if (!inopen) 11550Sstevel@tonic-gate error(0); 11560Sstevel@tonic-gate else { 11570Sstevel@tonic-gate if(vcnt < 0) { 11580Sstevel@tonic-gate vcnt = -vcnt; 11590Sstevel@tonic-gate if(state == VISUAL) 11600Sstevel@tonic-gate vclear(); 11610Sstevel@tonic-gate else if(state == CRTOPEN) 11620Sstevel@tonic-gate vcnt = 0; 11630Sstevel@tonic-gate } 11640Sstevel@tonic-gate vdirty(0, lines); 11650Sstevel@tonic-gate if (sig) 11660Sstevel@tonic-gate vrepaint(cursor); 11670Sstevel@tonic-gate } 11680Sstevel@tonic-gate } 11690Sstevel@tonic-gate #endif 11700Sstevel@tonic-gate 11710Sstevel@tonic-gate unsigned char *nextchr(cursor) 11720Sstevel@tonic-gate unsigned char *cursor; 11730Sstevel@tonic-gate { 11740Sstevel@tonic-gate 11750Sstevel@tonic-gate wchar_t wchar; 11760Sstevel@tonic-gate int length; 11770Sstevel@tonic-gate length = mbtowc(&wchar, (char *)cursor, MULTI_BYTE_MAX); 11780Sstevel@tonic-gate if(length <= 0) 11790Sstevel@tonic-gate return(++cursor); 11800Sstevel@tonic-gate return(cursor + length); 11810Sstevel@tonic-gate } 11820Sstevel@tonic-gate 11830Sstevel@tonic-gate unsigned char *lastchr(linebuf, cursor) 11840Sstevel@tonic-gate unsigned char *linebuf, *cursor; 11850Sstevel@tonic-gate { 11860Sstevel@tonic-gate wchar_t wchar; 11870Sstevel@tonic-gate int length; 11880Sstevel@tonic-gate unsigned char *ccursor, *ocursor; 11890Sstevel@tonic-gate if(cursor == linebuf) 11900Sstevel@tonic-gate return(linebuf - 1); 11910Sstevel@tonic-gate ccursor = ocursor = linebuf; 11920Sstevel@tonic-gate while(ccursor < cursor) { 11930Sstevel@tonic-gate length = mbtowc(&wchar, (char *)ccursor, MULTI_BYTE_MAX); 11940Sstevel@tonic-gate ocursor = ccursor; 11950Sstevel@tonic-gate if(length <= 0) 11960Sstevel@tonic-gate ccursor++; 11970Sstevel@tonic-gate else 11980Sstevel@tonic-gate ccursor += length; 11990Sstevel@tonic-gate } 12000Sstevel@tonic-gate return(ocursor); 12010Sstevel@tonic-gate } 12020Sstevel@tonic-gate 1203*802Scf46844 int 1204*802Scf46844 ixlatctl(int flag) 12050Sstevel@tonic-gate { 12060Sstevel@tonic-gate static struct strioctl sb = {0, 0, 0, 0}; 12070Sstevel@tonic-gate 12080Sstevel@tonic-gate if (!(MULTI_BYTE_MAX > 1)) 12090Sstevel@tonic-gate return (0); 12100Sstevel@tonic-gate 12110Sstevel@tonic-gate switch (flag) { 12120Sstevel@tonic-gate case 0: 12130Sstevel@tonic-gate sb.ic_cmd = EUC_MSAVE; 12140Sstevel@tonic-gate sb.ic_len = 0; 12150Sstevel@tonic-gate sb.ic_dp = 0; 12160Sstevel@tonic-gate if (ioctl(0, I_STR, &sb) < 0) 12170Sstevel@tonic-gate return (-1); 12180Sstevel@tonic-gate return (0); 12190Sstevel@tonic-gate case 1: 12200Sstevel@tonic-gate sb.ic_cmd = EUC_MREST; 12210Sstevel@tonic-gate sb.ic_len = 0; 12220Sstevel@tonic-gate sb.ic_dp = 0; 12230Sstevel@tonic-gate if (ioctl(0, I_STR, &sb) < 0) 12240Sstevel@tonic-gate return (-1); 12250Sstevel@tonic-gate return (0); 12260Sstevel@tonic-gate case 11: 12270Sstevel@tonic-gate return (0); 12280Sstevel@tonic-gate default: 12290Sstevel@tonic-gate return (-1); 12300Sstevel@tonic-gate } 12310Sstevel@tonic-gate } 12320Sstevel@tonic-gate #ifndef PRESUNEUC 12330Sstevel@tonic-gate 12340Sstevel@tonic-gate /* locale specific initialization */ 1235*802Scf46844 void 1236*802Scf46844 localize(void) 12370Sstevel@tonic-gate { 12380Sstevel@tonic-gate wchar_t fillerchar; 12390Sstevel@tonic-gate extern int wdchkind(); 12400Sstevel@tonic-gate extern int wdbindf(); 12410Sstevel@tonic-gate extern wchar_t *wddelim(); 12420Sstevel@tonic-gate extern wchar_t mcfiller(); 12430Sstevel@tonic-gate 12440Sstevel@tonic-gate wdwc = wdchkind; 12450Sstevel@tonic-gate wdbdg = wdbindf; 12460Sstevel@tonic-gate wddlm = wddelim; 12470Sstevel@tonic-gate mcfllr = mcfiller; 12480Sstevel@tonic-gate mc_wrap = 1; 12490Sstevel@tonic-gate fillerchar = mcfiller(); 12500Sstevel@tonic-gate mc_filler = isascii(fillerchar) ? (fillerchar & 0x7f) : '~'; 12510Sstevel@tonic-gate } 12520Sstevel@tonic-gate #endif /* PRESUNEUC */ 1253