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