1 /*
2  * This code contains changes by
3  *      Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved.
4  *
5  * Conditions 1, 2, and 4 and the no-warranty notice below apply
6  * to these changes.
7  *
8  *
9  * Copyright (c) 1980, 1993
10  * 	The Regents of the University of California.  All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  * 	This product includes software developed by the University of
23  * 	California, Berkeley and its contributors.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  *
41  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  *   Redistributions of source code and documentation must retain the
47  *    above copyright notice, this list of conditions and the following
48  *    disclaimer.
49  *   Redistributions in binary form must reproduce the above copyright
50  *    notice, this list of conditions and the following disclaimer in the
51  *    documentation and/or other materials provided with the distribution.
52  *   All advertising materials mentioning features or use of this software
53  *    must display the following acknowledgement:
54  *      This product includes software developed or owned by Caldera
55  *      International, Inc.
56  *   Neither the name of Caldera International, Inc. nor the names of
57  *    other contributors may be used to endorse or promote products
58  *    derived from this software without specific prior written permission.
59  *
60  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
61  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
62  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64  * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
65  * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
66  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
67  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
68  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
69  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
70  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
71  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72  *
73  *	from ex.h	7.7.1.1 (Berkeley) 8/12/86
74  *
75  *	@(#)ex.h	1.53 (gritter) 2/17/05
76  */
77 
78 /*
79  * Ex version 3 (see exact version in ex_version.c).
80  *
81  * Mark Horton, UC Berkeley
82  * Bill Joy, UC Berkeley
83  * November 1979
84  *
85  * Changes by Gunnar Ritter, Freiburg i. Br., Germany
86  * May 2000
87  *
88  * This file contains most of the declarations common to a large number
89  * of routines.  The file ex_vis.h contains declarations
90  * which are used only inside the screen editor.
91  * The file config.h contains parameters which can be diddled per installation.
92  * The file ex_tune.h contains parameters which should be changed by
93  * maintainers only.
94  *
95  * The declarations relating to the argument list, regular expressions,
96  * the temporary file data structure used by the editor
97  * and the data describing terminals are each fairly substantial and
98  * are kept in the files ex_{argv,re,temp,tty}.h which
99  * we #include separately.
100  *
101  * If you are going to dig into ex, you should look at the outline of the
102  * distribution of the code into files at the beginning of ex.c and ex_v.c.
103  * Code which is similar to that of ed is lightly or undocumented in spots
104  * (e.g. the regular expression code).  Newer code (e.g. open and visual)
105  * is much more carefully documented, and still rough in spots.
106  *
107  * Please forward bug reports to
108  *
109  *	Mark Horton
110  *	Computer Science Division, EECS
111  *	EVANS HALL
112  *	U.C. Berkeley 94704
113  *	(415) 642-4948
114  *	(415) 642-1024 (dept. office)
115  *
116  * or to csvax.mark@berkeley on the ARPA-net.  I would particularly like to hear
117  * of additional terminal descriptions you add to the termcap data base.
118  */
119 
120 #include <sys/types.h>
121 #include <sys/param.h>
122 #include <sys/stat.h>
123 #include <ctype.h>
124 #include <errno.h>
125 #include <signal.h>
126 #include <setjmp.h>
127 
128 #include <stdarg.h>
129 #include <string.h>
130 #include <stdlib.h>
131 
132 #ifdef	BIT8
133 #ifndef	ISO8859_1
134 #include <locale.h>
135 #endif
136 #endif
137 
138 #ifdef	MB
139 #include <wchar.h>
140 #include <wctype.h>
141 #endif
142 
143 #include <termios.h>
144 #include <fcntl.h>
145 #include <unistd.h>
146 #include <limits.h>
147 #ifndef	TIOCGWINSZ
148 #include <sys/ioctl.h>
149 #endif
150 
151 #include "config.h"
152 
153 typedef	void	(*shand)(int);
154 #ifdef	signal
155 #undef	signal
156 #endif
157 #define	signal(a, b)	setsig((a), (b))
158 
159 /*
160  * Avoid clobbering of automatic variables with an ANSI C compiler.
161  */
162 #define		CLOBBGRD(a)	(void)(&(a));
163 
164 #ifndef	MB_LEN_MAX
165 #define	MB_LEN_MAX	1
166 #endif
167 
168 /*
169  * Feature dependency checks.
170  */
171 #ifdef	ISO8859_1
172 #ifndef	BIT8
173 #define	BIT8
174 #endif
175 #endif
176 
177 #ifndef	LISPCODE
178 #define	LISPCODE
179 #endif
180 #ifndef	CHDIR
181 #define	CHDIR
182 #endif
183 
184 #ifndef var
185 #define var	extern
186 #endif
187 
188 #ifndef	VMUNIX
189 typedef	short	line;
190 #else
191 typedef	int	line;
192 #endif
193 
194 typedef	short	bool;
195 
196 #ifdef	LARGEF
197 typedef	off_t	bloc;
198 #else
199 typedef	short	bloc;
200 #endif
201 
202 #ifdef	VMUNIX
203 #ifdef	LARGEF
204 typedef	off_t	bbloc;
205 #else
206 typedef	int	bbloc;
207 #endif
208 #else
209 typedef	short	bbloc;
210 #endif
211 
212 /*
213  * The editor does not normally use the standard i/o library.  Because
214  * we expect the editor to be a heavily used program and because it
215  * does a substantial amount of input/output processing it is appropriate
216  * for it to call low level read/write primitives directly.  In fact,
217  * when debugging the editor we use the standard i/o library.  In any
218  * case the editor needs a printf which prints through "putchar" ala the
219  * old version 6 printf.  Thus we normally steal a copy of the "printf.c"
220  * and "strout" code from the standard i/o library and mung it for our
221  * purposes to avoid dragging in the stdio library headers, etc if we
222  * are not debugging.  Such a modified printf exists in "printf.c" here.
223  */
224 #ifdef TRACE
225 #	include <stdio.h>
226 	var	FILE	*trace;
227 	var	bool	trubble;
228 	var	bool	techoin;
229 	var	char	tracbuf[BUFSIZ];
230 #	undef	putchar
231 #	undef	getchar
232 
233 #else	/* !TRACE */
234 
235 #ifndef	BUFSIZ
236 #ifdef	LINE_MAX
237 #define	BUFSIZ	LINE_MAX	/* POSIX line size */
238 #else	/* !LINE_MAX */
239 #ifdef	VMUNIX
240 #define	BUFSIZ	1024
241 #else	/* !VMUNIX */
242 #ifdef	u370
243 #define	BUFSIZ	4096
244 #else	/* !u370 */
245 #define	BUFSIZ	512
246 #endif	/* !u370 */
247 #endif
248 #endif	/* !VMUNIX */
249 #endif	/* !LINE_MAX */
250 
251 #ifdef	NULL
252 #undef	NULL
253 #endif
254 #ifdef	EOF
255 #undef	EOF
256 #endif
257 #ifdef	printf
258 #undef	printf
259 #endif
260 #ifdef	vprintf
261 #undef	vprintf
262 #endif
263 #ifdef	getchar
264 #undef	getchar
265 #endif
266 #ifdef	putchar
267 #undef	putchar
268 #endif
269 
270 #define	NULL	0
271 #define	EOF	-1
272 
273 #endif	/* !TRACE */
274 
275 typedef	sigjmp_buf	JMP_BUF;
276 #define	SETJMP(a)	sigsetjmp(a, 1)
277 #define	LONGJMP(a, b)	siglongjmp(a, b)
278 
279 #ifndef	MAXBSIZE
280 #define	MAXBSIZE	8192	/* Same as in 4.2BSD */
281 #endif
282 
283 #include "ex_tune.h"
284 #include "ex_vars.h"
285 
286 /*
287  * Options in the editor are referred to usually by "value(name)" where
288  * name is all uppercase, i.e. "value(PROMPT)".  This is actually a macro
289  * which expands to a fixed field in a static structure and so generates
290  * very little code.  The offsets for the option names in the structure
291  * are generated automagically from the structure initializing them in
292  * ex_data.c... see the shell script "makeoptions".
293  */
294 struct	option {
295 	char	*oname;
296 	char	*oabbrev;
297 	short	otype;		/* Types -- see below */
298 	short	odefault;	/* Default value */
299 	short	ovalue;		/* Current value */
300 	char	*osvalue;
301 };
302 
303 #define	ONOFF	0
304 #define	NUMERIC	1
305 #define	STRING	2		/* SHELL or DIRECTORY */
306 #define	OTERM	3
307 
308 #define	value(a)	options[a].ovalue
309 #define	svalue(a)	options[a].osvalue
310 
311 extern	 struct	option options[NOPTS + 1];
312 
313 /*
314  * Character constants and bits
315  *
316  * The editor uses the QUOTE bit as a flag to pass on with characters
317  * e.g. to the putchar routine.  The editor never uses a simple char variable.
318  * Only arrays of and pointers to characters are used and parameters and
319  * registers are never declared character.
320  */
321 #ifdef	CTRL
322 #undef	CTRL
323 #endif
324 #define	CTRL(c)	((c) & 037)
325 #define	NL	CTRL('j')
326 #define	CR	CTRL('m')
327 #define	DELETE	0177		/* See also ATTN, QUIT in ex_tune.h */
328 #define	ESCAPE	033
329 
330 /*
331  * BIT8 and MB routines by Gunnar Ritter 2000, 2004.
332  *
333  * -DISO8859_1 enables all characters >= 0240 regardless of
334  *  LC_CTYPE.
335  */
336 #define	INVBIT		0x20000000
337 #define	MULTICOL	0x40000000
338 
339 #if defined (MB)
340 
341 /*
342  * This type is used to represent a single character cell.
343  */
344 typedef int	cell;
345 var	int	TRIM;
346 var	int	QUOTE;
347 #define	printable(c)	(((c)&INVBIT) == 0 && \
348 		(mb_cur_max > 1 ? iswprint((c)&TRIM) : isprint((c)&TRIM)))
349 #define	ext(c)		(((c) & 0177) == 0)
350 
351 #elif defined (BIT8)
352 
353 typedef	short	cell;
354 #define	QUOTE		0400
355 #define	TRIM		0377
356 #ifndef	ISO8859_1
357 #define	printable(c)	isprint((c)&TRIM)
358 #else	/* ISO8859_1 */
359 #define	printable(c)	(((c) & 0140) && (c) != DELETE)
360 #endif	/* ISO8859_1 */
361 
362 #else	/* !BIT8 */
363 
364 typedef	char	cell;
365 #define	QUOTE		0200
366 #define	TRIM		0177
367 
368 #endif	/* !BIT8 */
369 
370 /*
371  * Miscellaneous random variables used in more than one place
372  */
373 var	bool	aiflag;		/* Append/change/insert with autoindent */
374 var	bool	anymarks;	/* We have used '[a-z] */
375 var	int	bsize;		/* Block size for disk i/o */
376 var	int	chng;		/* Warn "No write" */
377 var	char	*Command;
378 var	short	defwind;	/* -w# change default window size */
379 var	int	dirtcnt;	/* When >= MAXDIRT, should sync temporary */
380 var	bool	dosusp;		/* Do SIGTSTP in visual when ^Z typed */
381 var	bool	edited;		/* Current file is [Edited] */
382 var	line	*endcore;	/* Last available core location */
383 extern	bool	endline;	/* Last cmd mode command ended with \n */
384 #ifndef VMUNIX
385 var	short	erfile;		/* Error message file unit */
386 #endif
387 var	line	*fendcore;	/* First address in line pointer space */
388 var	char	file[FNSIZE];	/* Working file name */
389 var	bool	fixedzero;	/* zero file size was fixed (for visual) */
390 var	char	genbuf[MAXBSIZE]; /* Working buffer when manipulating linebuf */
391 var	bool	hush;		/* Command line option - was given, hush up! */
392 var	char	*globp;		/* (Untyped) input string to command mode */
393 var	bool	holdcm;		/* Don't cursor address */
394 var	bool	inappend;	/* in ex command append mode */
395 var	bool	inglobal;	/* Inside g//... or v//... */
396 var	char	*initev;	/* Initial : escape for visual */
397 var	bool	inopen;		/* Inside open or visual */
398 var	char	*input;		/* Current position in cmd line input buffer */
399 var	bool	intty;		/* Input is a tty */
400 var	short	io;		/* General i/o unit (auto-closed on error!) */
401 extern	int	lastc;		/* Last character ret'd from cmd input */
402 var	bool	laste;		/* Last command was an "e" (or "rec") */
403 var	char	lastmac;	/* Last macro called for ** */
404 var	char	lasttag[TAGSIZE];	/* Last argument to a tag command */
405 var	char	*linebp;	/* Used in substituting in \n */
406 var	char	linebuf[LBSIZE];	/* The primary line buffer */
407 var	bool	listf;		/* Command should run in list mode */
408 var	line	names['z'-'a'+2];	/* Mark registers a-z,' */
409 var	int	notecnt;	/* Count for notify (to visual from cmd) */
410 var	bool	numberf;	/* Command should run in number mode */
411 var	char	obuf[BUFSIZ];	/* Buffer for tty output */
412 var	shand	oldhup;		/* Previous SIGHUP handler */
413 var	shand	oldquit;	/* Previous SIGQUIT handler */
414 #ifdef	SIGXFSZ
415 var	shand	oldxfsz;	/* Previous SIGXFSZ handler */
416 #endif
417 var	short	oprompt;	/* Saved during source */
418 extern	unsigned short	ospeed;		/* Output speed (from gtty) */
419 var	int	otchng;		/* Backup tchng to find changes in macros */
420 var	int	peekc;		/* Peek ahead character (cmd mode input) */
421 var	char	*pkill[2];	/* Trim for put with ragged (LISP) delete */
422 var	bool	pfast;		/* Have stty -nl'ed to go faster */
423 var	pid_t	pid;		/* Process id of child */
424 var	pid_t	ppid;		/* Process id of parent (e.g. main ex proc) */
425 var	JMP_BUF	resetlab;	/* For error throws to top level (cmd mode) */
426 var	pid_t	rpid;		/* Pid returned from wait() */
427 var	bool	recov;		/* A `n' command is executed as `recov' */
428 var	bool	ruptible;	/* Interruptible is normal state */
429 var	bool	seenprompt;	/* 1 if have gotten user input */
430 var	bool	shudclob;	/* Have a prompt to clobber (e.g. on ^D) */
431 var	int	status;		/* Status returned from wait() */
432 var	int	tchng;		/* If nonzero, then [Modified] */
433 extern	int	tfile;		/* Temporary file unit */
434 var	bool	tflag;		/* -t option given on command line */
435 var	bool	vcatch;		/* Want to catch an error (open/visual) */
436 var	bool	verbose;	/* -V option; print command input to stderr */
437 var	JMP_BUF	vreslab;	/* For error throws to a visual catch */
438 var	bool	writing;	/* 1 if in middle of a file write */
439 var	int	xchng;		/* Suppresses multiple "No writes" in !cmd */
440 var	int	failed;		/* exit with a non-zero status */
441 var	int	exitoneof;	/* exit command loop on EOF */
442 
443 /*
444  * Macros
445  */
446 #define	CP(a, b)	(ignore(movestr(a, b)))
447 			/*
448 			 * FIXUNDO: do we want to mung undo vars?
449 			 * Usually yes unless in a macro or global.
450 			 */
451 #define FIXUNDO		(inopen >= 0 && (inopen || !inglobal))
452 #define ckaw()		{if (chng && value(AUTOWRITE)) wop(0);}
453 #define	copy(a,b,c)	Copy((char *) (a), (char *) (b), (c))
454 #define	eq(a, b)	((a) && (b) && strcmp(a, b) == 0)
455 #define	getexit(a)	copy(a, resetlab, sizeof (JMP_BUF))
456 #define	lastchar()	lastc
457 #define	outchar(c)	(*Outchar)(c)
458 #define	pastwh()	(ignore(skipwh()))
459 #define	pline(no)	(*Pline)(no)
460 #define	reset()		LONGJMP(resetlab,1)
461 #define	resexit(a)	copy(resetlab, a, sizeof (JMP_BUF))
462 #define	setexit()	SETJMP(resetlab)
463 #define	setlastchar(c)	lastc = c
464 #define	ungetchar(c)	peekc = c
465 
466 #define	CATCH		vcatch = 1; if (SETJMP(vreslab) == 0) {
467 #define	ONERR		} else { vcatch = 0;
468 #define	ENDCATCH	} vcatch = 0;
469 
470 /*
471  * Environment like memory
472  */
473 var	char	altfile[FNSIZE];	/* Alternate file name */
474 extern	char	direct[ONMSZ];		/* Temp file goes here */
475 extern	char	shell[ONMSZ];		/* Copied to be settable */
476 extern	char	ttylongname[ONMSZ];	/* A long and pretty name */
477 var	char	uxb[UXBSIZE + 2];	/* Last !command for !! */
478 
479 /*
480  * The editor data structure for accessing the current file consists
481  * of an incore array of pointers into the temporary file tfile.
482  * Each pointer is 15 bits (the low bit is used by global) and is
483  * padded with zeroes to make an index into the temp file where the
484  * actual text of the line is stored.
485  *
486  * To effect undo, copies of affected lines are saved after the last
487  * line considered to be in the buffer, between dol and unddol.
488  * During an open or visual, which uses the command mode undo between
489  * dol and unddol, a copy of the entire, pre-command buffer state
490  * is saved between unddol and truedol.
491  */
492 var	line	*addr1;			/* First addressed line in a command */
493 var	line	*addr2;			/* Second addressed line */
494 var	line	*dol;			/* Last line in buffer */
495 var	line	*dot;			/* Current line */
496 var	line	*one;			/* First line */
497 var	line	*truedol;		/* End of all lines, including saves */
498 var	line	*unddol;		/* End of undo saved lines */
499 var	line	*zero;			/* Points to empty slot before one */
500 
501 /*
502  * Undo information
503  *
504  * For most commands we save lines changed by salting them away between
505  * dol and unddol before they are changed (i.e. we save the descriptors
506  * into the temp file tfile which is never garbage collected).  The
507  * lines put here go back after unddel, and to complete the undo
508  * we delete the lines [undap1,undap2).
509  *
510  * Undoing a move is much easier and we treat this as a special case.
511  * Similarly undoing a "put" is a special case for although there
512  * are lines saved between dol and unddol we don't stick these back
513  * into the buffer.
514  */
515 var	short	undkind;
516 
517 var	line	*unddel;	/* Saved deleted lines go after here */
518 var	line	*undap1;	/* Beginning of new lines */
519 var	line	*undap2;	/* New lines end before undap2 */
520 var	line	*undadot;	/* If we saved all lines, dot reverts here */
521 
522 #define	UNDCHANGE	0
523 #define	UNDMOVE		1
524 #define	UNDALL		2
525 #define	UNDNONE		3
526 #define	UNDPUT		4
527 
528 extern	int	(*Outchar)(int);
529 extern	void	(*Pline)(int);
530 extern	int	(*Putchar)(int);
531 
532 #define	NOSTR	(char *) 0
533 #define	NOLINE	(line *) 0
534 
535 #define	ignore(a)	a
536 #define	ignorf(a)	a
537 
538 #ifdef	LANGMSG
539 #include <nl_types.h>
540 var	nl_catd	catd;
541 #else	/* !LANGMSG */
542 #define	catgets(a, b, c, d)	(d)
543 #endif	/* !LANGMSG */
544 var	char	*cntrlhm;
545 
546 #include "ex_proto.h"
547 
548 var	int	mb_cur_max;
549 #ifdef	MB
550 #define	nextc(c, s, n)	(mb_cur_max > 1 && *(s) & 0200 ? \
551 			((n) = mbtowi(&(c), (s), mb_cur_max), \
552 		 	(n) = ((n) > 0 ? (n) : (n) < 0 ? (c=WEOF, 1) : 1)) :\
553 		((c) = *(s) & 0377, (n) = 1))
554 #define	colsc(c)	(mb_cur_max > 1 && ((c)&0177) != (c) ? wcwidth(c) : 1)
555 #define	skipleft(l, p)	(mb_cur_max > 1 && ((p)[0]&0200 || \
556 				(p)>(l) && (p)[-1]&0200) ? wskipleft(l, p) : -1)
557 #define	skipright(l, p)	(mb_cur_max > 1 && (p)>=(l) && (p)[0]&0200 ? \
558 				wskipright(l, p) : 1)
559 #define	samechar(cp, c)	(mb_cur_max > 1 && *(cp)&0200 ? wsamechar(cp, c) : \
560 				(*(cp)&0377) == c)
561 #define	xisdigit(c)	(mb_cur_max > 1 ? iswdigit(c) : isdigit(c))
562 #define	xisalpha(c)	(mb_cur_max > 1 ? iswalpha(c) : isalpha(c))
563 #define	xisalnum(c)	(mb_cur_max > 1 ? iswalnum(c) : isalnum(c))
564 #define	xisspace(c)	(mb_cur_max > 1 ? iswspace(c) : isspace(c))
565 #define	xisupper(c)	(mb_cur_max > 1 ? iswupper(c) : isupper(c))
566 #define	xislower(c)	(mb_cur_max > 1 ? iswlower(c) : islower(c))
567 #define	xtolower(c)	(mb_cur_max > 1 ? towlower(c) : tolower(c))
568 #define	xtoupper(c)	(mb_cur_max > 1 ? towupper(c) : toupper(c))
569 #else	/* !MB */
570 #define	nextc(c, s, n)	((c) = *(s) & 0377, (n) = 1)
571 #define	colsc(c)	(1)
572 #define	skipleft(l, p)	(-1)
573 #define	skipright(l, p)	(1)
574 #define	samechar(cp, c)	(*(cp)&0377 == c)
575 #define	xisdigit(c)	isdigit(c)
576 #define	xisalpha(c)	isalpha(c)
577 #define	xisalnum(c)	isalnum(c)
578 #define	xisspace(c)	isspace(c)
579 #define	xisupper(c)	isupper(c)
580 #define	xislower(c)	islower(c)
581 #define	xtolower(c)	tolower(c)
582 #define	xtoupper(c)	toupper(c)
583 #endif	/* !MB */
584