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 */