xref: /illumos-gate/usr/src/cmd/vi/port/ex.h (revision 0f1f7826)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	  All Rights Reserved  	*/
28 
29 /* Copyright (c) 1981 Regents of the University of California */
30 
31 #ifndef _EX_H
32 #define	_EX_H
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /*
39  * This file contains most of the declarations common to a large number
40  * of routines.  The file ex_vis.h contains declarations
41  * which are used only inside the screen editor.
42  * The file ex_tune.h contains parameters which can be diddled per installation.
43  *
44  * The declarations relating to the argument list, regular expressions,
45  * the temporary file data structure used by the editor
46  * and the data describing terminals are each fairly substantial and
47  * are kept in the files ex_{argv,re,temp,tty}.h which
48  * we #include separately.
49  *
50  * If you are going to dig into ex, you should look at the outline of the
51  * distribution of the code into files at the beginning of ex.c and ex_v.c.
52  * Code which is similar to that of ed is lightly or undocumented in spots
53  * (e.g. the regular expression code).  Newer code (e.g. open and visual)
54  * is much more carefully documented, and still rough in spots.
55  *
56  */
57 #ifdef UCBV7
58 #include <whoami.h>
59 #endif
60 #include <sys/types.h>
61 #include <ctype.h>
62 #include <errno.h>
63 #include <signal.h>
64 #include <setjmp.h>
65 #include <sys/stat.h>
66 #include <stdlib.h>
67 #include <limits.h>
68 #include <libintl.h>
69 
70 #define MULTI_BYTE_MAX MB_LEN_MAX
71 #define FTYPE(A)	(A.st_mode)
72 #define FMODE(A)	(A.st_mode)
73 #define	IDENTICAL(A,B)	(A.st_dev==B.st_dev && A.st_ino==B.st_ino)
74 #define ISBLK(A)	((A.st_mode & S_IFMT) == S_IFBLK)
75 #define ISCHR(A)	((A.st_mode & S_IFMT) == S_IFCHR)
76 #define ISDIR(A)	((A.st_mode & S_IFMT) == S_IFDIR)
77 #define ISFIFO(A)	((A.st_mode & S_IFMT) == S_IFIFO)
78 #define ISREG(A)	((A.st_mode & S_IFMT) == S_IFREG)
79 
80 #ifdef USG
81 #include <termio.h>
82 typedef struct termios SGTTY;
83 #else
84 #include <sgtty.h>
85 typedef struct sgttyb SGTTY;
86 #endif
87 
88 #ifdef PAVEL
89 #define SGTTY struct sgttyb	/* trick Pavel curses to not include <curses.h> */
90 #endif
91 typedef char bool;
92 typedef unsigned long chtype;
93 #include <term.h>
94 #define bool vi_bool
95 #ifdef PAVEL
96 #undef SGTTY
97 #endif
98 #ifndef var
99 #define var	extern
100 #endif
101 var char *exit_bold;		/* string to exit standout mode */
102 
103 /*
104  *	The following little dance copes with the new USG tty handling.
105  *	This stuff has the advantage of considerable flexibility, and
106  *	the disadvantage of being incompatible with anything else.
107  *	The presence of the symbol USG will indicate the new code:
108  *	in this case, we define CBREAK (because we can simulate it exactly),
109  *	but we won't actually use it, so we set it to a value that will
110  *	probably blow the compilation if we goof up.
111  */
112 #ifdef USG
113 #define CBREAK xxxxx
114 #endif
115 
116 #ifndef VMUNIX
117 typedef	short	line;
118 #else
119 typedef	int	line;
120 #endif
121 typedef	short	bool;
122 
123 #include "ex_tune.h"
124 #include "ex_vars.h"
125 /*
126  * Options in the editor are referred to usually by "value(vi_name)" where
127  * name is all uppercase, i.e. "value(vi_PROMPT)".  This is actually a macro
128  * which expands to a fixed field in a static structure and so generates
129  * very little code.  The offsets for the option names in the structure
130  * are generated automagically from the structure initializing them in
131  * ex_data.c... see the shell script "makeoptions".
132  */
133 struct	option {
134 	unsigned char	*oname;
135 	unsigned char	*oabbrev;
136 	short	otype;		/* Types -- see below */
137 	short	odefault;	/* Default value */
138 	short	ovalue;		/* Current value */
139 	unsigned char	*osvalue;
140 };
141 
142 #define	ONOFF	0
143 #define	NUMERIC	1
144 #define	STRING	2		/* SHELL or DIRECTORY */
145 #define	OTERM	3
146 
147 #define	value(a)	options[a].ovalue
148 #define	svalue(a)	options[a].osvalue
149 
150 extern	 struct	option options[vi_NOPTS + 1];
151 
152 
153 /*
154  * The editor does not normally use the standard i/o library.  Because
155  * we expect the editor to be a heavily used program and because it
156  * does a substantial amount of input/output processing it is appropriate
157  * for it to call low level read/write primitives directly.  In fact,
158  * when debugging the editor we use the standard i/o library.  In any
159  * case the editor needs a printf which prints through "putchar" ala the
160  * old version 6 printf.  Thus we normally steal a copy of the "printf.c"
161  * and "strout" code from the standard i/o library and mung it for our
162  * purposes to avoid dragging in the stdio library headers, etc if we
163  * are not debugging.  Such a modified printf exists in "printf.c" here.
164  */
165 #ifdef TRACE
166 #include <stdio.h>
167 	var	FILE	*trace;
168 	var	bool	trubble;
169 	var	bool	techoin;
170 	var	unsigned char	tracbuf[BUFSIZ];
171 #undef	putchar
172 #undef	getchar
173 #else
174 /*
175  * Warning: do not change BUFSIZ without also changing LBSIZE in ex_tune.h
176  * Running with BUFSIZ set to anything besides what is in <stdio.h> is
177  * not recommended, if you use stdio.
178  */
179 #ifdef u370
180 #define	BUFSIZE	4096
181 #else
182 #define	BUFSIZE	(LINE_MAX*2)
183 #endif
184 #undef	NULL
185 #define	NULL	0
186 #undef	EOF
187 #define	EOF	-1
188 #endif
189 
190 /*
191  * Character constants and bits
192  *
193  * The editor uses the QUOTE bit as a flag to pass on with characters
194  * e.g. to the putchar routine.  The editor never uses a simple char variable.
195  * Only arrays of and pointers to characters are used and parameters and
196  * registers are never declared character.
197  */
198 #define	QUOTE	020000000000
199 #define	TRIM	017777777777
200 #define	NL	'\n'
201 #define	CR	'\r'
202 #define	DELETE	0177		/* See also ATTN, QUIT in ex_tune.h */
203 #define	ESCAPE	033
204 #undef	CTRL
205 #define	CTRL(c)	(c & 037)
206 
207 /*
208  * Miscellaneous random variables used in more than one place
209  */
210 var bool multibyte;
211 var	bool	aiflag;		/* Append/change/insert with autoindent */
212 var	bool	tagflg;		/* set for -t option and :tag command */
213 var	bool	anymarks;	/* We have used '[a-z] */
214 var	int	chng;		/* Warn "No write" */
215 var	unsigned char	*Command;
216 var	short	defwind;	/* -w# change default window size */
217 var	int	dirtcnt;	/* When >= MAXDIRT, should sync temporary */
218 #ifdef SIGTSTP
219 var	bool	dosusp;		/* Do SIGTSTP in visual when ^Z typed */
220 #endif
221 var	bool	edited;		/* Current file is [Edited] */
222 var	line	*endcore;	/* Last available core location */
223 extern	 bool	endline;	/* Last cmd mode command ended with \n */
224 var	line	*fendcore;	/* First address in line pointer space */
225 var	unsigned char	file[FNSIZE];	/* Working file name */
226 var	unsigned char	genbuf[LBSIZE];	/* Working buffer when manipulating linebuf */
227 var	bool	hush;		/* Command line option - was given, hush up! */
228 var	unsigned char	*globp;		/* (Untyped) input string to command mode */
229 var	bool	holdcm;		/* Don't cursor address */
230 var	bool	inappend;	/* in ex command append mode */
231 var	bool	inglobal;	/* Inside g//... or v//... */
232 var	unsigned char	*initev;	/* Initial : escape for visual */
233 var	bool	inopen;		/* Inside open or visual */
234 var	unsigned char	*input;		/* Current position in cmd line input buffer */
235 var	bool	intty;		/* Input is a tty */
236 var	short	io;		/* General i/o unit (auto-closed on error!) */
237 extern	 short	lastc;		/* Last character ret'd from cmd input */
238 var	bool	laste;		/* Last command was an "e" (or "rec") */
239 var	unsigned char	lastmac;	/* Last macro called for ** */
240 var	unsigned char	lasttag[TAGSIZE];	/* Last argument to a tag command */
241 var	unsigned char	*linebp;	/* Used in substituting in \n */
242 var	unsigned char	linebuf[LBSIZE];	/* The primary line buffer */
243 var	bool	listf;		/* Command should run in list mode */
244 var	line	names['z'-'a'+2];	/* Mark registers a-z,' */
245 var	int	notecnt;	/* Count for notify (to visual from cmd) */
246 var	bool	numberf;	/* Command should run in number mode */
247 var	unsigned char	obuf[BUFSIZE];	/* Buffer for tty output */
248 var	short	oprompt;	/* Saved during source */
249 var	short	ospeed;		/* Output speed (from gtty) */
250 var	int	otchng;		/* Backup tchng to find changes in macros */
251 var	int	peekc;		/* Peek ahead character (cmd mode input) */
252 var	unsigned char	*pkill[2];	/* Trim for put with ragged (LISP) delete */
253 var	bool	pfast;		/* Have stty -nl'ed to go faster */
254 var	pid_t	pid;		/* Process id of child */
255 var	pid_t	ppid;		/* Process id of parent (e.g. main ex proc) */
256 var	jmp_buf	resetlab;	/* For error throws to top level (cmd mode) */
257 var	pid_t	rpid;		/* Pid returned from wait() */
258 var	bool	ruptible;	/* Interruptible is normal state */
259 var	bool	seenprompt;	/* 1 if have gotten user input */
260 var	bool	shudclob;	/* Have a prompt to clobber (e.g. on ^D) */
261 var	int	status;		/* Status returned from wait() */
262 var	int	tchng;		/* If nonzero, then [Modified] */
263 extern	short	tfile;		/* Temporary file unit */
264 var	bool	vcatch;		/* Want to catch an error (open/visual) */
265 var	jmp_buf	vreslab;	/* For error throws to a visual catch */
266 var	bool	writing;	/* 1 if in middle of a file write */
267 var	int	xchng;		/* Suppresses multiple "No writes" in !cmd */
268 #ifndef PRESUNEUC
269 var	char	mc_filler;	/* Right margin filler for multicolumn char */
270 var	bool	mc_wrap;	/* Multicolumn character wrap at right margin */
271 #endif /* PRESUNEUC */
272 var     int     inexrc;         /* boolean: in .exrc initialization */
273 
274 extern	int	termiosflag;	/* flag for using termios */
275 
276 /*
277  * Macros
278  */
279 #define	CP(a, b)	((void)strcpy(a, b))
280 			/*
281 			 * FIXUNDO: do we want to mung undo vars?
282 			 * Usually yes unless in a macro or global.
283 			 */
284 #define FIXUNDO		(inopen >= 0 && (inopen || !inglobal))
285 #define ckaw()		{if (chng && value(vi_AUTOWRITE) && !value(vi_READONLY)) \
286 				wop(0);\
287 			}
288 #define	copy(a,b,c)	Copy((char *) (a), (char *) (b), (c))
289 #define	eq(a, b)	((a) && (b) && strcmp(a, b) == 0)
290 #define	getexit(a)	copy(a, resetlab, sizeof (jmp_buf))
291 #define	lastchar()	lastc
292 #define	outchar(c)	(*Outchar)(c)
293 #define	pastwh()	((void)skipwh())
294 #define	pline(no)	(*Pline)(no)
295 #define	reset()		longjmp(resetlab,1)
296 #define	resexit(a)	copy(resetlab, a, sizeof (jmp_buf))
297 #define	setexit()	setjmp(resetlab)
298 #define	setlastchar(c)	lastc = c
299 #define	ungetchar(c)	peekc = c
300 
301 #define	CATCH		vcatch = 1; if (setjmp(vreslab) == 0) {
302 #define	ONERR		} else { vcatch = 0;
303 #define	ENDCATCH	} vcatch = 0;
304 
305 /*
306  * Environment like memory
307  */
308 var	unsigned char	altfile[FNSIZE];	/* Alternate file name */
309 extern	unsigned char	direct[ONMSZ];		/* Temp file goes here */
310 extern	unsigned char	shell[ONMSZ];		/* Copied to be settable */
311 var	unsigned char	uxb[UXBSIZE + 2];	/* Last !command for !! */
312 
313 /*
314  * The editor data structure for accessing the current file consists
315  * of an incore array of pointers into the temporary file tfile.
316  * Each pointer is 15 bits (the low bit is used by global) and is
317  * padded with zeroes to make an index into the temp file where the
318  * actual text of the line is stored.
319  *
320  * To effect undo, copies of affected lines are saved after the last
321  * line considered to be in the buffer, between dol and unddol.
322  * During an open or visual, which uses the command mode undo between
323  * dol and unddol, a copy of the entire, pre-command buffer state
324  * is saved between unddol and truedol.
325  */
326 var	line	*addr1;			/* First addressed line in a command */
327 var	line	*addr2;			/* Second addressed line */
328 var	line	*dol;			/* Last line in buffer */
329 var	line	*dot;			/* Current line */
330 var	line	*one;			/* First line */
331 var	line	*truedol;		/* End of all lines, including saves */
332 var	line	*unddol;		/* End of undo saved lines */
333 var	line	*zero;			/* Points to empty slot before one */
334 
335 /*
336  * Undo information
337  *
338  * For most commands we save lines changed by salting them away between
339  * dol and unddol before they are changed (i.e. we save the descriptors
340  * into the temp file tfile which is never garbage collected).  The
341  * lines put here go back after unddel, and to complete the undo
342  * we delete the lines [undap1,undap2).
343  *
344  * Undoing a move is much easier and we treat this as a special case.
345  * Similarly undoing a "put" is a special case for although there
346  * are lines saved between dol and unddol we don't stick these back
347  * into the buffer.
348  */
349 var	short	undkind;
350 
351 var	line	*unddel;	/* Saved deleted lines go after here */
352 var	line	*undap1;	/* Beginning of new lines */
353 var	line	*undap2;	/* New lines end before undap2 */
354 var	line	*undadot;	/* If we saved all lines, dot reverts here */
355 
356 #define	UNDCHANGE	0
357 #define	UNDMOVE		1
358 #define	UNDALL		2
359 #define	UNDNONE		3
360 #define	UNDPUT		4
361 
362 /*
363  * Various miscellaneous flags and buffers needed by the encryption routines.
364  */
365 #define	KSIZE   9       /* key size for encryption */
366 var	int	xflag;		/* True if we are in encryption mode */
367 var	int	xtflag;		/* True if the temp file is being encrypted */
368 var	int	kflag;		/* True if the key has been accepted */
369 var	int	crflag;		/* True if the key has been accepted  and the file
370 				   being read is ciphertext
371 				 */
372 var	int	perm[2];	/* pipe connection to crypt for file being edited */
373 var	int	tperm[2];	/* pipe connection to crypt for temporary file */
374 var	int permflag;
375 var 	int tpermflag;
376 var	unsigned char	*key;
377 var	unsigned char	crbuf[CRSIZE];
378 char	*getpass();
379 
380 var	bool	write_quit;	/* True if executing a 'wq' command */
381 var	int	errcnt;		/* number of error/warning messages in */
382 				/*	editing session (global flag)  */
383 /*
384  * Function type definitions
385  */
386 #define	NOSTR	(char *) 0
387 #define	NOLINE	(line *) 0
388 
389 #define	setterm visetterm
390 #define	draino vidraino
391 #define	gettmode vigettmode
392 
393 extern	int	(*Outchar)();
394 extern	int	(*Pline)();
395 extern	int	(*Putchar)();
396 var	void	(*oldhup)();
397 int	(*setlist())();
398 int	(*setnorm())();
399 int	(*setnorm())();
400 int	(*setnumb())();
401 #ifndef PRESUNEUC
402 int	(*wdwc)(wchar_t);	/* tells kind of word character */
403 int	(*wdbdg)(wchar_t, wchar_t, int);	/* tells word binding force */
404 wchar_t	*(*wddlm)(wchar_t, wchar_t, int);	/* tells desired delimiter */
405 wchar_t	(*mcfllr)(void);	/* tells multicolumn filler character */
406 #endif /* PRESUNEUC */
407 line	*address();
408 unsigned char	*cgoto();
409 unsigned char	*genindent();
410 unsigned char	*getblock();
411 char	*getenv();
412 line	*getmark();
413 unsigned char	*mesg();
414 unsigned char	*place();
415 unsigned char	*plural();
416 line	*scanfor();
417 void setin(line *);
418 unsigned char	*strend();
419 unsigned char	*tailpath();
420 char	*tgetstr();
421 char	*tgoto();
422 char	*ttyname();
423 line	*vback();
424 unsigned char	*vfindcol();
425 unsigned char	*vgetline();
426 unsigned char	*vinit();
427 unsigned char	*vpastwh();
428 unsigned char	*vskipwh();
429 int	put(void);
430 int	putreg(unsigned char);
431 int	YANKreg(int);
432 int	delete(bool);
433 int	vi_filter();
434 int	getfile();
435 int	getsub();
436 int	gettty();
437 int	join(int);
438 int	listchar(wchar_t);
439 int	normchar(wchar_t);
440 int	normline(void);
441 int	numbline(int);
442 var	void	(*oldquit)();
443 
444 void	onhup(int);
445 void	onintr(int);
446 void	oncore(int);
447 #ifdef CBREAK
448 void	vintr(int);
449 #endif
450 void	onsusp(int);
451 int	putch(char);
452 int	plodput(char);
453 int	vputch(char);
454 
455 void	shift(int, int);
456 int	termchar(wchar_t);
457 int	vfilter();
458 int	vshftop();
459 int	yank(void);
460 unsigned char *lastchr();
461 unsigned char *nextchr();
462 bool putoctal;
463 
464 void	error();
465 void	error0(void);
466 void error1(unsigned char *);
467 void fixol(void);
468 void resetflav(void);
469 void serror(unsigned char *, unsigned char *);
470 void setflav(void);
471 void tailprim(unsigned char *, int, bool);
472 void vcontin(bool);
473 void squish(void);
474 void move1(int, line *);
475 void pragged(bool);
476 void zop2(int, int);
477 void plines(line *, line *, bool);
478 void pofix(void);
479 void undo(bool);
480 void somechange(void);
481 void savetag(char *);
482 void unsavetag(void);
483 void checkjunk(unsigned char);
484 void getone(void);
485 void rop3(int);
486 void rop2(void);
487 void putfile(int);
488 void wrerror(void);
489 void clrstats(void);
490 void slobber(int);
491 void flush(void);
492 void flush1(void);
493 void flush2(void);
494 void fgoto(void);
495 void flusho(void);
496 void comprhs(int);
497 int dosubcon(bool, line *);
498 void ugo(int, int);
499 void dosub(void);
500 void snote(int, int);
501 void cerror(unsigned char *);
502 void unterm(void);
503 int setend(void);
504 void prall(void);
505 void propts(void);
506 void propt(struct option *);
507 void killcnt(int);
508 void markpr(line *);
509 void merror1(unsigned char *);
510 void notempty(void);
511 int qcolumn(unsigned char *, unsigned char *);
512 void netchange(int);
513 void putmk1(line *, int);
514 int nqcolumn(unsigned char *, unsigned char *);
515 void syserror(int);
516 void cleanup(bool);
517 void blkio(short, unsigned char *, int (*)());
518 void tflush(void);
519 short partreg(unsigned char);
520 void kshift(void);
521 void YANKline(void);
522 void rbflush(void);
523 void waitfor(void);
524 void ovbeg(void);
525 void fixzero(void);
526 void savevis(void);
527 void undvis(void);
528 void setwind(void);
529 void vok(wchar_t *, int);
530 void vsetsiz(int);
531 void vinslin(int, int, int);
532 void vopenup(int, bool, int);
533 void vadjAL(int, int);
534 void vup1(void);
535 void vmoveitup(int, bool);
536 void vscroll(int);
537 void vscrap(void);
538 void vredraw(int);
539 void vdellin(int, int, int);
540 void vadjDL(int, int);
541 void vsyncCL(void);
542 void vsync(int);
543 void vsync1(int);
544 void vcloseup(int, int);
545 void sethard(void);
546 void vdirty(int, int);
547 void setBUF(unsigned char *);
548 void addto(unsigned char *, unsigned char *);
549 void macpush();
550 void setalarm(void);
551 void cancelalarm(void);
552 void grabtag(void);
553 void prepapp(void);
554 void vremote();
555 void vsave(void);
556 void vzop(bool, int, int);
557 void warnf();
558 int wordof(unsigned char, unsigned char *);
559 void setpk(void);
560 void back1(void);
561 void vdoappend(unsigned char *);
562 void vclrbyte(wchar_t *, int);
563 void vclreol(void);
564 void vsetcurs(unsigned char *);
565 void vigoto(int, int);
566 void vcsync(void);
567 void vgotoCL(int);
568 void vgoto(int, int);
569 void vmaktop(int, wchar_t *);
570 void vrigid(void);
571 void vneedpos(int);
572 void vnpins(int);
573 void vishft(void);
574 void viin(wchar_t);
575 void godm(void);
576 void enddm(void);
577 void goim(void);
578 void endim(void);
579 void vjumpto(line *, unsigned char *, unsigned char);
580 void vup(int, int, bool);
581 void vdown(int, int, bool);
582 void vcontext(line *, unsigned char);
583 void vclean(void);
584 void vshow(line *, line*);
585 void vreset(bool);
586 void vroll(int);
587 void vrollR(int);
588 void vnline(unsigned char *);
589 void noerror();
590 void getaline(line);
591 void viprintf();
592 void gettmode(void);
593 void setterm(unsigned char *);
594 void draino(void);
595 int lfind();
596 void source();
597 void commands();
598 void addmac();
599 void vmoveto();
600 void vrepaint();
601 void getDOT(void);
602 void vclear(void);
603 
604 unsigned char *lastchr();
605 unsigned char *nextchr();
606 bool putoctal;
607 
608 void setdot1(void);
609 
610 #ifdef __cplusplus
611 }
612 #endif
613 
614 #endif /* _EX_H */
615