mirror of https://github.com/tildeclub/ex-vi.git
584 lines
19 KiB
C
584 lines
19 KiB
C
/*
|
|
* This code contains changes by
|
|
* Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved.
|
|
*
|
|
* Conditions 1, 2, and 4 and the no-warranty notice below apply
|
|
* to these changes.
|
|
*
|
|
*
|
|
* Copyright (c) 1980, 1993
|
|
* The Regents of the University of California. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by the University of
|
|
* California, Berkeley and its contributors.
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
*
|
|
* Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* Redistributions of source code and documentation must retain the
|
|
* above copyright notice, this list of conditions and the following
|
|
* disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed or owned by Caldera
|
|
* International, Inc.
|
|
* Neither the name of Caldera International, Inc. nor the names of
|
|
* other contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
|
|
* INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* from ex.h 7.7.1.1 (Berkeley) 8/12/86
|
|
*
|
|
* @(#)ex.h 1.53 (gritter) 2/17/05
|
|
*/
|
|
|
|
/*
|
|
* Ex version 3 (see exact version in ex_version.c).
|
|
*
|
|
* Mark Horton, UC Berkeley
|
|
* Bill Joy, UC Berkeley
|
|
* November 1979
|
|
*
|
|
* Changes by Gunnar Ritter, Freiburg i. Br., Germany
|
|
* May 2000
|
|
*
|
|
* This file contains most of the declarations common to a large number
|
|
* of routines. The file ex_vis.h contains declarations
|
|
* which are used only inside the screen editor.
|
|
* The file config.h contains parameters which can be diddled per installation.
|
|
* The file ex_tune.h contains parameters which should be changed by
|
|
* maintainers only.
|
|
*
|
|
* The declarations relating to the argument list, regular expressions,
|
|
* the temporary file data structure used by the editor
|
|
* and the data describing terminals are each fairly substantial and
|
|
* are kept in the files ex_{argv,re,temp,tty}.h which
|
|
* we #include separately.
|
|
*
|
|
* If you are going to dig into ex, you should look at the outline of the
|
|
* distribution of the code into files at the beginning of ex.c and ex_v.c.
|
|
* Code which is similar to that of ed is lightly or undocumented in spots
|
|
* (e.g. the regular expression code). Newer code (e.g. open and visual)
|
|
* is much more carefully documented, and still rough in spots.
|
|
*
|
|
* Please forward bug reports to
|
|
*
|
|
* Mark Horton
|
|
* Computer Science Division, EECS
|
|
* EVANS HALL
|
|
* U.C. Berkeley 94704
|
|
* (415) 642-4948
|
|
* (415) 642-1024 (dept. office)
|
|
*
|
|
* or to csvax.mark@berkeley on the ARPA-net. I would particularly like to hear
|
|
* of additional terminal descriptions you add to the termcap data base.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/param.h>
|
|
#include <sys/stat.h>
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <setjmp.h>
|
|
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef BIT8
|
|
#ifndef ISO8859_1
|
|
#include <locale.h>
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef MB
|
|
#include <wchar.h>
|
|
#include <wctype.h>
|
|
#endif
|
|
|
|
#include <termios.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <limits.h>
|
|
#ifndef TIOCGWINSZ
|
|
#include <sys/ioctl.h>
|
|
#endif
|
|
|
|
#include "config.h"
|
|
|
|
typedef void (*shand)(int);
|
|
#ifdef signal
|
|
#undef signal
|
|
#endif
|
|
#define signal(a, b) setsig((a), (b))
|
|
|
|
/*
|
|
* Avoid clobbering of automatic variables with an ANSI C compiler.
|
|
*/
|
|
#define CLOBBGRD(a) (void)(&(a));
|
|
|
|
#ifndef MB_LEN_MAX
|
|
#define MB_LEN_MAX 1
|
|
#endif
|
|
|
|
/*
|
|
* Feature dependency checks.
|
|
*/
|
|
#ifdef ISO8859_1
|
|
#ifndef BIT8
|
|
#define BIT8
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef LISPCODE
|
|
#define LISPCODE
|
|
#endif
|
|
#ifndef CHDIR
|
|
#define CHDIR
|
|
#endif
|
|
|
|
#ifndef var
|
|
#define var extern
|
|
#endif
|
|
|
|
#ifndef VMUNIX
|
|
typedef short line;
|
|
#else
|
|
typedef int line;
|
|
#endif
|
|
|
|
typedef short bool;
|
|
|
|
#ifdef LARGEF
|
|
typedef off_t bloc;
|
|
#else
|
|
typedef short bloc;
|
|
#endif
|
|
|
|
#ifdef VMUNIX
|
|
#ifdef LARGEF
|
|
typedef off_t bbloc;
|
|
#else
|
|
typedef int bbloc;
|
|
#endif
|
|
#else
|
|
typedef short bbloc;
|
|
#endif
|
|
|
|
/*
|
|
* The editor does not normally use the standard i/o library. Because
|
|
* we expect the editor to be a heavily used program and because it
|
|
* does a substantial amount of input/output processing it is appropriate
|
|
* for it to call low level read/write primitives directly. In fact,
|
|
* when debugging the editor we use the standard i/o library. In any
|
|
* case the editor needs a printf which prints through "putchar" ala the
|
|
* old version 6 printf. Thus we normally steal a copy of the "printf.c"
|
|
* and "strout" code from the standard i/o library and mung it for our
|
|
* purposes to avoid dragging in the stdio library headers, etc if we
|
|
* are not debugging. Such a modified printf exists in "printf.c" here.
|
|
*/
|
|
#ifdef TRACE
|
|
# include <stdio.h>
|
|
var FILE *trace;
|
|
var bool trubble;
|
|
var bool techoin;
|
|
var char tracbuf[BUFSIZ];
|
|
# undef putchar
|
|
# undef getchar
|
|
|
|
#else /* !TRACE */
|
|
|
|
#ifndef BUFSIZ
|
|
#ifdef LINE_MAX
|
|
#define BUFSIZ LINE_MAX /* POSIX line size */
|
|
#else /* !LINE_MAX */
|
|
#ifdef VMUNIX
|
|
#define BUFSIZ 1024
|
|
#else /* !VMUNIX */
|
|
#ifdef u370
|
|
#define BUFSIZ 4096
|
|
#else /* !u370 */
|
|
#define BUFSIZ 512
|
|
#endif /* !u370 */
|
|
#endif
|
|
#endif /* !VMUNIX */
|
|
#endif /* !LINE_MAX */
|
|
|
|
#ifdef NULL
|
|
#undef NULL
|
|
#endif
|
|
#ifdef EOF
|
|
#undef EOF
|
|
#endif
|
|
#ifdef printf
|
|
#undef printf
|
|
#endif
|
|
#ifdef vprintf
|
|
#undef vprintf
|
|
#endif
|
|
#ifdef getchar
|
|
#undef getchar
|
|
#endif
|
|
#ifdef putchar
|
|
#undef putchar
|
|
#endif
|
|
|
|
#define NULL 0
|
|
#define EOF -1
|
|
|
|
#endif /* !TRACE */
|
|
|
|
typedef sigjmp_buf JMP_BUF;
|
|
#define SETJMP(a) sigsetjmp(a, 1)
|
|
#define LONGJMP(a, b) siglongjmp(a, b)
|
|
|
|
#ifndef MAXBSIZE
|
|
#define MAXBSIZE 8192 /* Same as in 4.2BSD */
|
|
#endif
|
|
|
|
#include "ex_tune.h"
|
|
#include "ex_vars.h"
|
|
|
|
/*
|
|
* Options in the editor are referred to usually by "value(name)" where
|
|
* name is all uppercase, i.e. "value(PROMPT)". This is actually a macro
|
|
* which expands to a fixed field in a static structure and so generates
|
|
* very little code. The offsets for the option names in the structure
|
|
* are generated automagically from the structure initializing them in
|
|
* ex_data.c... see the shell script "makeoptions".
|
|
*/
|
|
struct option {
|
|
char *oname;
|
|
char *oabbrev;
|
|
short otype; /* Types -- see below */
|
|
short odefault; /* Default value */
|
|
short ovalue; /* Current value */
|
|
char *osvalue;
|
|
};
|
|
|
|
#define ONOFF 0
|
|
#define NUMERIC 1
|
|
#define STRING 2 /* SHELL or DIRECTORY */
|
|
#define OTERM 3
|
|
|
|
#define value(a) options[a].ovalue
|
|
#define svalue(a) options[a].osvalue
|
|
|
|
extern struct option options[NOPTS + 1];
|
|
|
|
/*
|
|
* Character constants and bits
|
|
*
|
|
* The editor uses the QUOTE bit as a flag to pass on with characters
|
|
* e.g. to the putchar routine. The editor never uses a simple char variable.
|
|
* Only arrays of and pointers to characters are used and parameters and
|
|
* registers are never declared character.
|
|
*/
|
|
#ifdef CTRL
|
|
#undef CTRL
|
|
#endif
|
|
#define CTRL(c) ((c) & 037)
|
|
#define NL CTRL('j')
|
|
#define CR CTRL('m')
|
|
#define DELETE 0177 /* See also ATTN, QUIT in ex_tune.h */
|
|
#define ESCAPE 033
|
|
|
|
/*
|
|
* BIT8 and MB routines by Gunnar Ritter 2000, 2004.
|
|
*
|
|
* -DISO8859_1 enables all characters >= 0240 regardless of
|
|
* LC_CTYPE.
|
|
*/
|
|
#define INVBIT 0x20000000
|
|
#define MULTICOL 0x40000000
|
|
|
|
#if defined (MB)
|
|
|
|
/*
|
|
* This type is used to represent a single character cell.
|
|
*/
|
|
typedef int cell;
|
|
var int TRIM;
|
|
var int QUOTE;
|
|
#define printable(c) (((c)&INVBIT) == 0 && \
|
|
(mb_cur_max > 1 ? iswprint((c)&TRIM) : isprint((c)&TRIM)))
|
|
#define ext(c) (((c) & 0177) == 0)
|
|
|
|
#elif defined (BIT8)
|
|
|
|
typedef short cell;
|
|
#define QUOTE 0400
|
|
#define TRIM 0377
|
|
#ifndef ISO8859_1
|
|
#define printable(c) isprint((c)&TRIM)
|
|
#else /* ISO8859_1 */
|
|
#define printable(c) (((c) & 0140) && (c) != DELETE)
|
|
#endif /* ISO8859_1 */
|
|
|
|
#else /* !BIT8 */
|
|
|
|
typedef char cell;
|
|
#define QUOTE 0200
|
|
#define TRIM 0177
|
|
|
|
#endif /* !BIT8 */
|
|
|
|
/*
|
|
* Miscellaneous random variables used in more than one place
|
|
*/
|
|
var bool aiflag; /* Append/change/insert with autoindent */
|
|
var bool anymarks; /* We have used '[a-z] */
|
|
var int bsize; /* Block size for disk i/o */
|
|
var int chng; /* Warn "No write" */
|
|
var char *Command;
|
|
var short defwind; /* -w# change default window size */
|
|
var int dirtcnt; /* When >= MAXDIRT, should sync temporary */
|
|
var bool dosusp; /* Do SIGTSTP in visual when ^Z typed */
|
|
var bool edited; /* Current file is [Edited] */
|
|
var line *endcore; /* Last available core location */
|
|
extern bool endline; /* Last cmd mode command ended with \n */
|
|
#ifndef VMUNIX
|
|
var short erfile; /* Error message file unit */
|
|
#endif
|
|
var line *fendcore; /* First address in line pointer space */
|
|
var char file[FNSIZE]; /* Working file name */
|
|
var bool fixedzero; /* zero file size was fixed (for visual) */
|
|
var char genbuf[MAXBSIZE]; /* Working buffer when manipulating linebuf */
|
|
var bool hush; /* Command line option - was given, hush up! */
|
|
var char *globp; /* (Untyped) input string to command mode */
|
|
var bool holdcm; /* Don't cursor address */
|
|
var bool inappend; /* in ex command append mode */
|
|
var bool inglobal; /* Inside g//... or v//... */
|
|
var char *initev; /* Initial : escape for visual */
|
|
var bool inopen; /* Inside open or visual */
|
|
var char *input; /* Current position in cmd line input buffer */
|
|
var bool intty; /* Input is a tty */
|
|
var short io; /* General i/o unit (auto-closed on error!) */
|
|
extern int lastc; /* Last character ret'd from cmd input */
|
|
var bool laste; /* Last command was an "e" (or "rec") */
|
|
var char lastmac; /* Last macro called for ** */
|
|
var char lasttag[TAGSIZE]; /* Last argument to a tag command */
|
|
var char *linebp; /* Used in substituting in \n */
|
|
var char linebuf[LBSIZE]; /* The primary line buffer */
|
|
var bool listf; /* Command should run in list mode */
|
|
var line names['z'-'a'+2]; /* Mark registers a-z,' */
|
|
var int notecnt; /* Count for notify (to visual from cmd) */
|
|
var bool numberf; /* Command should run in number mode */
|
|
var char obuf[BUFSIZ]; /* Buffer for tty output */
|
|
var shand oldhup; /* Previous SIGHUP handler */
|
|
var shand oldquit; /* Previous SIGQUIT handler */
|
|
#ifdef SIGXFSZ
|
|
var shand oldxfsz; /* Previous SIGXFSZ handler */
|
|
#endif
|
|
var short oprompt; /* Saved during source */
|
|
extern unsigned short ospeed; /* Output speed (from gtty) */
|
|
var int otchng; /* Backup tchng to find changes in macros */
|
|
var int peekc; /* Peek ahead character (cmd mode input) */
|
|
var char *pkill[2]; /* Trim for put with ragged (LISP) delete */
|
|
var bool pfast; /* Have stty -nl'ed to go faster */
|
|
var pid_t pid; /* Process id of child */
|
|
var pid_t ppid; /* Process id of parent (e.g. main ex proc) */
|
|
var JMP_BUF resetlab; /* For error throws to top level (cmd mode) */
|
|
var pid_t rpid; /* Pid returned from wait() */
|
|
var bool recov; /* A `n' command is executed as `recov' */
|
|
var bool ruptible; /* Interruptible is normal state */
|
|
var bool seenprompt; /* 1 if have gotten user input */
|
|
var bool shudclob; /* Have a prompt to clobber (e.g. on ^D) */
|
|
var int status; /* Status returned from wait() */
|
|
var int tchng; /* If nonzero, then [Modified] */
|
|
extern int tfile; /* Temporary file unit */
|
|
var bool tflag; /* -t option given on command line */
|
|
var bool vcatch; /* Want to catch an error (open/visual) */
|
|
var bool verbose; /* -V option; print command input to stderr */
|
|
var JMP_BUF vreslab; /* For error throws to a visual catch */
|
|
var bool writing; /* 1 if in middle of a file write */
|
|
var int xchng; /* Suppresses multiple "No writes" in !cmd */
|
|
var int failed; /* exit with a non-zero status */
|
|
var int exitoneof; /* exit command loop on EOF */
|
|
|
|
/*
|
|
* Macros
|
|
*/
|
|
#define CP(a, b) (ignore(movestr(a, b)))
|
|
/*
|
|
* FIXUNDO: do we want to mung undo vars?
|
|
* Usually yes unless in a macro or global.
|
|
*/
|
|
#define FIXUNDO (inopen >= 0 && (inopen || !inglobal))
|
|
#define ckaw() {if (chng && value(AUTOWRITE)) wop(0);}
|
|
#define copy(a,b,c) Copy((char *) (a), (char *) (b), (c))
|
|
#define eq(a, b) ((a) && (b) && strcmp(a, b) == 0)
|
|
#define getexit(a) copy(a, resetlab, sizeof (JMP_BUF))
|
|
#define lastchar() lastc
|
|
#define outchar(c) (*Outchar)(c)
|
|
#define pastwh() (ignore(skipwh()))
|
|
#define pline(no) (*Pline)(no)
|
|
#define reset() LONGJMP(resetlab,1)
|
|
#define resexit(a) copy(resetlab, a, sizeof (JMP_BUF))
|
|
#define setexit() SETJMP(resetlab)
|
|
#define setlastchar(c) lastc = c
|
|
#define ungetchar(c) peekc = c
|
|
|
|
#define CATCH vcatch = 1; if (SETJMP(vreslab) == 0) {
|
|
#define ONERR } else { vcatch = 0;
|
|
#define ENDCATCH } vcatch = 0;
|
|
|
|
/*
|
|
* Environment like memory
|
|
*/
|
|
var char altfile[FNSIZE]; /* Alternate file name */
|
|
extern char direct[ONMSZ]; /* Temp file goes here */
|
|
extern char shell[ONMSZ]; /* Copied to be settable */
|
|
extern char ttylongname[ONMSZ]; /* A long and pretty name */
|
|
var char uxb[UXBSIZE + 2]; /* Last !command for !! */
|
|
|
|
/*
|
|
* The editor data structure for accessing the current file consists
|
|
* of an incore array of pointers into the temporary file tfile.
|
|
* Each pointer is 15 bits (the low bit is used by global) and is
|
|
* padded with zeroes to make an index into the temp file where the
|
|
* actual text of the line is stored.
|
|
*
|
|
* To effect undo, copies of affected lines are saved after the last
|
|
* line considered to be in the buffer, between dol and unddol.
|
|
* During an open or visual, which uses the command mode undo between
|
|
* dol and unddol, a copy of the entire, pre-command buffer state
|
|
* is saved between unddol and truedol.
|
|
*/
|
|
var line *addr1; /* First addressed line in a command */
|
|
var line *addr2; /* Second addressed line */
|
|
var line *dol; /* Last line in buffer */
|
|
var line *dot; /* Current line */
|
|
var line *one; /* First line */
|
|
var line *truedol; /* End of all lines, including saves */
|
|
var line *unddol; /* End of undo saved lines */
|
|
var line *zero; /* Points to empty slot before one */
|
|
|
|
/*
|
|
* Undo information
|
|
*
|
|
* For most commands we save lines changed by salting them away between
|
|
* dol and unddol before they are changed (i.e. we save the descriptors
|
|
* into the temp file tfile which is never garbage collected). The
|
|
* lines put here go back after unddel, and to complete the undo
|
|
* we delete the lines [undap1,undap2).
|
|
*
|
|
* Undoing a move is much easier and we treat this as a special case.
|
|
* Similarly undoing a "put" is a special case for although there
|
|
* are lines saved between dol and unddol we don't stick these back
|
|
* into the buffer.
|
|
*/
|
|
var short undkind;
|
|
|
|
var line *unddel; /* Saved deleted lines go after here */
|
|
var line *undap1; /* Beginning of new lines */
|
|
var line *undap2; /* New lines end before undap2 */
|
|
var line *undadot; /* If we saved all lines, dot reverts here */
|
|
|
|
#define UNDCHANGE 0
|
|
#define UNDMOVE 1
|
|
#define UNDALL 2
|
|
#define UNDNONE 3
|
|
#define UNDPUT 4
|
|
|
|
extern int (*Outchar)(int);
|
|
extern void (*Pline)(int);
|
|
extern int (*Putchar)(int);
|
|
|
|
#define NOSTR (char *) 0
|
|
#define NOLINE (line *) 0
|
|
|
|
#define ignore(a) a
|
|
#define ignorf(a) a
|
|
|
|
#ifdef LANGMSG
|
|
#include <nl_types.h>
|
|
var nl_catd catd;
|
|
#else /* !LANGMSG */
|
|
#define catgets(a, b, c, d) (d)
|
|
#endif /* !LANGMSG */
|
|
var char *cntrlhm;
|
|
|
|
#include "ex_proto.h"
|
|
|
|
var int mb_cur_max;
|
|
#ifdef MB
|
|
#define nextc(c, s, n) (mb_cur_max > 1 && *(s) & 0200 ? \
|
|
((n) = mbtowi(&(c), (s), mb_cur_max), \
|
|
(n) = ((n) > 0 ? (n) : (n) < 0 ? (c=WEOF, 1) : 1)) :\
|
|
((c) = *(s) & 0377, (n) = 1))
|
|
#define colsc(c) (mb_cur_max > 1 && ((c)&0177) != (c) ? wcwidth(c) : 1)
|
|
#define skipleft(l, p) (mb_cur_max > 1 && ((p)[0]&0200 || \
|
|
(p)>(l) && (p)[-1]&0200) ? wskipleft(l, p) : -1)
|
|
#define skipright(l, p) (mb_cur_max > 1 && (p)>=(l) && (p)[0]&0200 ? \
|
|
wskipright(l, p) : 1)
|
|
#define samechar(cp, c) (mb_cur_max > 1 && *(cp)&0200 ? wsamechar(cp, c) : \
|
|
(*(cp)&0377) == c)
|
|
#define xisdigit(c) (mb_cur_max > 1 ? iswdigit(c) : isdigit(c))
|
|
#define xisalpha(c) (mb_cur_max > 1 ? iswalpha(c) : isalpha(c))
|
|
#define xisalnum(c) (mb_cur_max > 1 ? iswalnum(c) : isalnum(c))
|
|
#define xisspace(c) (mb_cur_max > 1 ? iswspace(c) : isspace(c))
|
|
#define xisupper(c) (mb_cur_max > 1 ? iswupper(c) : isupper(c))
|
|
#define xislower(c) (mb_cur_max > 1 ? iswlower(c) : islower(c))
|
|
#define xtolower(c) (mb_cur_max > 1 ? towlower(c) : tolower(c))
|
|
#define xtoupper(c) (mb_cur_max > 1 ? towupper(c) : toupper(c))
|
|
#else /* !MB */
|
|
#define nextc(c, s, n) ((c) = *(s) & 0377, (n) = 1)
|
|
#define colsc(c) (1)
|
|
#define skipleft(l, p) (-1)
|
|
#define skipright(l, p) (1)
|
|
#define samechar(cp, c) (*(cp)&0377 == c)
|
|
#define xisdigit(c) isdigit(c)
|
|
#define xisalpha(c) isalpha(c)
|
|
#define xisalnum(c) isalnum(c)
|
|
#define xisspace(c) isspace(c)
|
|
#define xisupper(c) isupper(c)
|
|
#define xislower(c) islower(c)
|
|
#define xtolower(c) tolower(c)
|
|
#define xtoupper(c) toupper(c)
|
|
#endif /* !MB */
|