1: /*************************************************************************** 2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * 3: * is provided to you without charge, and with no warranty. You may give * 4: * away copies of JOVE, including sources, provided that this notice is * 5: * included in all the files. * 6: ***************************************************************************/ 7: 8: /* jove.h header file to be included by EVERYONE */ 9: 10: 11: #include <setjmp.h> 12: 13: #ifndef TUNED 14: # include "tune.h" 15: #endif 16: 17: #ifndef MAC 18: # include <sys/types.h> 19: #else 20: # include <types.h> 21: #endif 22: 23: 24: #ifdef MSDOS 25: #include <string.h> 26: #endif 27: 28: 29: #if !(defined(MSDOS) || defined(MAC)) 30: #define void int 31: #endif 32: 33: #if !(defined(IBMPC) || defined(MAC)) 34: # define TERMCAP 35: # define ASCII 36: #endif 37: 38: #ifdef ASCII /* seven bit characters */ 39: # define NCHARS 0200 40: #else 41: # define NCHARS 0400 42: #endif 43: #define CHARMASK (NCHARS -1) 44: 45: #define private static 46: 47: #ifndef BSD4_2 48: # ifdef MENLO_JCL 49: # ifndef EUNICE 50: # define signal sigset 51: # endif 52: # endif /* MENLO_JCL */ 53: #endif 54: 55: #define EOF -1 56: 57: #ifdef MSDOS 58: # define NULL ((char *)0) 59: # define NIL ((char *)0) 60: #else 61: # ifdef MAC 62: # define NULL 0L 63: # define NIL 0L 64: # else 65: # define NULL 0 66: # define NIL 0 67: # endif /* MAC */ 68: #endif /* MSDOS */ 69: /* kinds of regular expression compiles */ 70: #define NORM 0 /* nothing special */ 71: #define OKAY_RE 1 /* allow regular expressions */ 72: #define IN_CB 2 /* in curly brace; implies OKAY_RE */ 73: 74: /* return codes for command completion (all < 0 because >= 0 are 75: legitimate offsets into array of strings */ 76: 77: #define AMBIGUOUS -2 /* matches more than one at this point */ 78: #define UNIQUE -3 /* matches only one string */ 79: #define ORIGINAL -4 /* matches no strings at all! */ 80: #define NULLSTRING -5 /* just hit return without typing anything */ 81: 82: /* values for the `flags' argument to complete */ 83: #define NOTHING 0 /* opposite of RET_STATE */ 84: #define RET_STATE 1 /* return state when we hit return */ 85: #define RCOMMAND 2 /* we are reading a joverc file */ 86: #define CASEIND 4 /* map all to lower case */ 87: 88: #define SAVE 01 /* this macro needs saving to a file */ 89: 90: #define LBSIZE BUFSIZ /* same as a logical disk block */ 91: #ifndef MSDOS 92: #define FILESIZE 256 93: #else /* MSDOS */ 94: #define FILESIZE 64 95: #endif /* MSDOS */ 96: 97: #define FORWARD 1 98: #define BACKWARD -1 99: 100: #define CTL(c) (c & 037) 101: #define META(c) (c | 0200) 102: #define RUBOUT '\177' 103: #define LF CTL('J') 104: #define CR CTL('M') 105: #define BS CTL('H') 106: #define ESC '\033' 107: 108: #define HALF(wp) ((wp->w_height - 1) / 2) 109: #define IsModified(b) (b->b_modified) 110: #define SIZE(wp) (wp->w_height - 1) 111: #define SavLine(a, b) (a->l_dline = putline(b)) 112: #define SetLine(line) DotTo(line, 0) 113: #define bobp() (firstp(curline) && bolp()) 114: #define bolp() (curchar == 0) 115: #define eobp() (lastp(curline) && eolp()) 116: #define eolp() (linebuf[curchar] == '\0') 117: #define firstp(line) (line == curbuf->b_first) 118: #define getDOT() getline(curline->l_dline, linebuf) 119: #define isdirty(line) (line->l_dline & DIRTY) 120: #define lastp(line) (line == curbuf->b_last) 121: #define makedirty(line) line->l_dline |= DIRTY 122: #define one_windp() (fwind->w_next == fwind) 123: 124: #define CharUpcase(c) (CaseEquiv[c]) 125: 126: extern int BufSize; 127: 128: #define ARG_CMD 1 129: #define LINECMD 2 130: #define KILLCMD 3 /* so we can merge kills */ 131: #define YANKCMD 4 /* so we can do ESC Y (yank-pop) */ 132: 133: /* Buffer type */ 134: 135: #define B_SCRATCH 1 /* for internal things, e.g. minibuffer ... */ 136: #define B_FILE 2 /* normal file (We Auto-save these.) */ 137: #define B_PROCESS 3 /* process output in this buffer */ 138: 139: /* Major modes */ 140: #define FUNDAMENTAL 0 /* Fundamental mode */ 141: #define TEXT 1 /* Text mode */ 142: #define CMODE 2 /* C mode */ 143: #ifdef LISP 144: # define LISPMODE 3 /* Lisp mode */ 145: # define NMAJORS 4 146: #else 147: # define NMAJORS 3 148: #endif 149: 150: /* Minor Modes */ 151: #define Indent (1 << 0) /* indent same as previous line after return */ 152: #define ShowMatch (1 << 1) /* paren flash mode */ 153: #define Fill (1 << 2) /* text fill mode */ 154: #define OverWrite (1 << 3) /* over write mode */ 155: #define Abbrev (1 << 4) /* abbrev mode */ 156: 157: #define BufMinorMode(b, x) (b->b_minor & x) 158: 159: #define MinorMode(x) BufMinorMode(curbuf, x) 160: #define MajorMode(x) (curbuf->b_major == x) 161: #define SetMajor(x) ((curbuf->b_major = x), UpdModLine = YES) 162: 163: extern char CharTable[NMAJORS][NCHARS]; 164: extern char CaseEquiv[NCHARS]; 165: 166: /* setjmp/longjmp args for DoKeys() mainjmp */ 167: #define FIRSTCALL 0 168: #define ERROR 1 169: #define COMPLAIN 2 /* do the error without a getDOT */ 170: #define QUIT 3 /* leave this level of recursion */ 171: 172: #define QUIET 1 /* sure, why not? */ 173: 174: #define YES 1 175: #define NO 0 176: #define TRUE 1 177: #define FALSE 0 178: #define ON 1 179: #define OFF 0 180: #define YES_NODIGIT 2 181: 182: #define INT_OKAY 0 183: #define INT_BAD -1 184: 185: extern char *Mainbuf, 186: *HomeDir, /* home directory */ 187: key_strokes[], /* strokes that make up current command */ 188: *Inputp; 189: 190: extern int HomeLen; /* length of home directory */ 191: 192: extern char NullStr[]; 193: 194: #if defined(VMUNIX)||defined(MSDOS) 195: extern char genbuf[LBSIZE], 196: linebuf[LBSIZE], 197: iobuff[LBSIZE]; 198: #else 199: extern char *genbuf, /* scratch pad points at s_genbuf (see main()) */ 200: *linebuf, /* points at s_linebuf */ 201: *iobuff; /* for file reading ... points at s_iobuff */ 202: #endif 203: 204: extern int InJoverc, 205: Interactive; 206: 207: #define READ 0 208: #define WRITE 1 209: extern int errno; 210: 211: extern jmp_buf mainjmp; 212: 213: #ifdef IPROCS 214: typedef struct process Process; 215: #endif 216: typedef struct window Window; 217: typedef struct position Bufpos; 218: typedef struct mark Mark; 219: typedef struct buffer Buffer; 220: typedef struct line Line; 221: typedef struct iobuf IOBUF; 222: typedef struct data_obj { 223: int Type; 224: char *Name; 225: } data_obj; /* points to cmd, macro, or variable */ 226: 227: typedef data_obj *keymap[NCHARS]; 228: 229: struct line { 230: Line *l_prev, /* pointer to prev */ 231: *l_next; /* pointer to next */ 232: disk_line l_dline; /* pointer to disk location */ 233: }; 234: 235: #ifdef IPROCS 236: struct process { 237: Process *p_next; 238: #ifdef PIPEPROCS 239: int p_toproc, /* read p_fromproc and write p_toproc */ 240: p_portpid, /* pid of child (the portsrv) */ 241: p_pid; /* pid of real child i.e. not portsrv */ 242: #else 243: int p_fd, /* file descriptor of pty? opened r/w */ 244: p_pid; /* pid of child (the shell) */ 245: #endif 246: Buffer *p_buffer; /* add output to end of this buffer */ 247: char *p_name; /* ... */ 248: char p_state, /* State */ 249: p_howdied, /* Killed? or Exited? */ 250: p_reason; /* If signaled, p_reason is the signal; else 251: it is the the exit code */ 252: Mark *p_mark; /* where output left us */ 253: data_obj 254: *p_cmd; /* command to call when process dies */ 255: }; 256: #endif /* IPROCS */ 257: 258: struct window { 259: Window *w_prev, /* circular list */ 260: *w_next; 261: Buffer *w_bufp; /* buffer associated with this window */ 262: Line *w_top, /* top line */ 263: *w_line; /* current line */ 264: int w_char, 265: w_height, /* window height */ 266: w_topnum, /* line number of the topline */ 267: w_dotcol, /* UpdWindow sets this ... */ 268: w_dotline, /* ... and this */ 269: w_flags, 270: #define W_TOPGONE 01 271: #define W_CURGONE 02 /* topline (curline) of window has been deleted 272: since the last time a redisplay was called */ 273: #define W_VISSPACE 04 274: #define W_NUMLINES 010 275: w_LRscroll; /* amount of LeftRight scrolling in window */ 276: #ifdef MAC 277: int w_topline; /* row number of top line in window */ 278: char **w_control; /* scroll bar for window */ 279: #endif 280: }; 281: 282: extern Window *fwind, /* first window in list */ 283: *curwind; /* current window */ 284: 285: struct position { 286: Line *p_line; 287: int p_char; 288: }; 289: 290: struct mark { 291: Line *m_line; 292: int m_char; 293: Mark *m_next; /* list of marks */ 294: #define M_FIXED 00 295: #define M_FLOATER 01 296: #define M_BIG_DELETE 02 297: char m_flags; /* FLOATERing mark? */ 298: }; 299: 300: struct buffer { 301: #ifdef MAC 302: int Type; /* kludge... to look like a data_obj */ 303: char *Name; /* Name will not be used */ 304: #endif 305: Buffer *b_next; /* next buffer in chain */ 306: char *b_name, /* buffer name */ 307: *b_fname; /* file name associated with buffer */ 308: dev_t b_dev; /* device of file name. */ 309: ino_t b_ino; /* inode of file name */ 310: time_t b_mtime; /* last modify time ... 311: to detect two people writing 312: to the same file */ 313: Line *b_first, /* pointer to first line in list */ 314: *b_dot, /* current line */ 315: *b_last; /* last line in list */ 316: int b_char; /* current character in line */ 317: 318: #define NMARKS 8 /* number of marks in the ring */ 319: 320: Mark *b_markring[NMARKS], /* new marks are pushed here */ 321: *b_marks; /* all the marks for this buffer */ 322: char b_themark, /* current mark (in b_markring) */ 323: b_type, /* file, scratch, process, iprocess */ 324: b_ntbf, /* needs to be found when we 325: first select? */ 326: b_modified; /* is the buffer modified? */ 327: int b_major, /* major mode */ 328: b_minor; /* and minor mode */ 329: keymap *b_keybinds; /* local bindings (if any) */ 330: #ifdef IPROCS 331: Process *b_process; /* process we're attached to */ 332: #endif 333: }; 334: 335: struct macro { 336: int Type; /* in this case a macro */ 337: char *Name; /* name is always second ... */ 338: int m_len, /* length of macro so we can use ^@ */ 339: m_buflen, /* memory allocated for it */ 340: m_flags; 341: char *m_body; /* actual body of the macro */ 342: struct macro 343: *m_nextm; 344: }; 345: 346: struct variable { 347: int Type; /* in this case a variable */ 348: char *Name; /* name is always second */ 349: int *v_value, 350: v_flags; 351: }; 352: 353: struct cmd { 354: int Type; 355: char *Name; 356: #ifdef MAC 357: void (*c_proc)(); 358: #else 359: int (*c_proc)(); 360: #endif 361: #ifdef MAC 362: char c_map; /* prefix map for About Jove... */ 363: char c_key; /* key binding for About Jove... */ 364: #endif 365: }; 366: 367: extern keymap mainmap, /* various key maps */ 368: pref1map, 369: pref2map, 370: miscmap; 371: #ifdef MAC /* used in About Jove... */ 372: #define F_MAINMAP '\001' 373: #define F_PREF1MAP '\002' 374: #define F_PREF2MAP '\003' 375: #endif 376: 377: extern data_obj *LastCmd; /* last command invoked */ 378: 379: extern char *ProcFmt; 380: 381: extern struct cmd commands[]; 382: extern struct macro *macros; 383: extern struct variable variables[]; 384: 385: extern struct macro 386: *macstack[], 387: KeyMacro; 388: 389: #define FUNCTION 1 390: #define VARIABLE 2 391: #define MACRO 3 392: #ifdef MAC 393: # define BUFFER 6 /* menus can point to buffers, too */ 394: # define STRING 7 /* a menu string or divider */ 395: #endif 396: 397: #define TYPEMASK 07 398: #define MAJOR_MODE 010 399: #define MINOR_MODE 020 400: #define DefMajor(x) (FUNCTION|MAJOR_MODE|(x << 8)) 401: #define DefMinor(x) (FUNCTION|MINOR_MODE|(x << 8)) 402: 403: extern Buffer *world, /* first buffer */ 404: *curbuf; /* pointer into world for current buffer */ 405: 406: #define curline curbuf->b_dot 407: #define curchar curbuf->b_char 408: 409: #define NUMKILLS 10 /* number of kills saved in the kill ring */ 410: 411: #ifdef MAC /* when doing ~DIRTY, we need high bits set */ 412: # define DIRTY (disk_line) 01 /* just needs updating for some reason */ 413: #else 414: # define DIRTY 01 /* just needs updating for some reason */ 415: #endif 416: #define MODELINE 02 /* this is a modeline */ 417: #define L_MOD 04 /* this line has been modified internally */ 418: 419: struct scrimage { 420: int s_offset, /* offset to start printing at */ 421: s_flags, /* various flags */ 422: s_id, /* which buffer line */ 423: s_vln; /* Visible Line Number */ 424: Line *s_lp; /* so we can turn off red bit */ 425: Window *s_window; /* window that contains this line */ 426: }; 427: 428: extern struct scrimage 429: *DesiredScreen, /* what we want */ 430: *PhysScreen; /* what we got */ 431: 432: /* Variable flags (that can be set). */ 433: #define V_BASE10 01 /* is integer in base 10 */ 434: #define V_BASE8 02 /* is integer in base 8 */ 435: #define V_BOOL 04 /* is a boolean */ 436: #define V_STRING 010 /* is a string */ 437: #define V_CHAR 020 /* is a character */ 438: #define V_FILENAME 040 /* a file name (implies V_STRING) */ 439: #define V_TYPEMASK 077 /* mask off the extra bits */ 440: #define V_MODELINE 0100 /* update modeline */ 441: #define V_CLRSCREEN 0200 /* clear and redraw screen */ 442: #define V_TTY_RESET 0400 /* redo the tty modes */ 443: 444: #ifdef MAC 445: #ifdef TXT_TO_C 446: int /* kludge, so setmaps will compile with variables */ 447: #else 448: extern int 449: #endif /* TXT_TO_C */ 450: #else 451: extern int 452: #endif /* MAC */ 453: 454: OKXonXoff, /* disable start/stop characters */ 455: MetaKey, /* this terminal has a meta key */ 456: VisBell, /* use visible bell (if possible) */ 457: WrapScan, /* make searches wrap */ 458: #ifndef MAC 459: phystab, /* terminal's tabstop settings */ 460: #endif 461: tabstop, /* expand tabs to this number of spaces */ 462: #ifdef BACKUPFILES 463: BkupOnWrite, /* make backup files when writing */ 464: #endif 465: RMargin, /* right margin */ 466: LMargin, /* left margin */ 467: ScrollStep, /* how should we scroll */ 468: #ifndef MAC 469: WtOnMk, /* write files on compile-it command */ 470: #endif 471: EndWNewline, /* end files with a blank line */ 472: MarkThresh, /* moves greater than MarkThresh will SetMark */ 473: PDelay, /* paren flash delay in tenths of a second */ 474: CIndIncrmt, /* how much each indentation level pushes 475: over in C mode */ 476: CreatMode, /* default mode for creat'ing files */ 477: CaseIgnore, /* case ignore search */ 478: #ifdef ABBREV 479: AutoCaseAbbrev, /* automatically do case on abbreviations */ 480: #endif 481: MarksShouldFloat, /* adjust marks on insertion/deletion */ 482: UseRE, /* use regular expressions in search */ 483: SyncFreq, /* how often to sync the file pointers */ 484: BriteMode, /* make the mode line inverse? */ 485: OkayBadChars, /* allow bad characters in files created 486: by JOVE */ 487: UpdFreq, /* how often to update modeline */ 488: UseBuffers, /* use buffers with Typeout() */ 489: #ifdef BIFF 490: BiffChk, /* turn off/on biff with entering/exiting jove */ 491: #endif 492: MailInt, /* mail check interval */ 493: #ifdef ID_CHAR 494: UseIC, /* whether or not to use i/d char 495: processesing */ 496: #endif 497: SExitChar, /* type this to stop i-search */ 498: AbortChar, /* cancels command input */ 499: IntChar, /* ttysets this to generate QUIT */ 500: DoEVexpand, /* treat $foo as environment variable */ 501: #ifdef F_COMPLETION 502: DispBadFs, /* display filenames with bad extensions? */ 503: #endif 504: #ifdef IBMPC 505: Fgcolor, 506: Bgcolor, 507: Mdcolor, 508: #endif /* IBMPC */ 509: #ifdef F_COMPLETION 510: DispBadFs, /* display filenames with bad extensions? */ 511: #endif 512: ScrollAll, /* we current line scrolls, scroll whole window? */ 513: #ifndef MAC 514: EWSize; /* size to make the error window */ 515: #else 516: Macmode, /* see mac.c */ 517: Keyonly, 518: Bufchange, 519: Modechange, 520: Windchange, 521: EventCmd; 522: #endif /* MAC */ 523: 524: #ifdef MAC 525: # ifdef TXT_TO_C /* kludge, for setmaps with variables */ 526: char 527: # else 528: extern char 529: # endif /* TXT_TO_C */ 530: #else 531: extern char 532: #endif /* MAC */ 533: 534: #ifndef MAC 535: ErrFmtStr[256], /* format string for parse errors */ 536: #endif 537: #ifdef IPROCS 538: proc_prompt[128], /* process prompt */ 539: #endif 540: #ifdef F_COMPLETION 541: BadExtensions[128], /* extensions (e.g., ".o" to ignore) */ 542: #endif 543: #ifdef CMT_FMT 544: CmtFmt[80], 545: #endif 546: ModeFmt[120], /* mode line format string */ 547: #ifdef UNIX 548: Mailbox[FILESIZE], /* mailbox name */ 549: #endif /* UNIX */ 550: TmpFilePath[FILESIZE], /* directory/device to store tmp files */ 551: TagFile[FILESIZE], /* default tag file */ 552: Shell[FILESIZE]; /* shell to use */ 553: 554: extern int 555: TOabort, /* flag set by Typeout() */ 556: io, /* file descriptor for reading and writing files */ 557: errormsg, /* last message was an error message 558: so don't erase the error before it 559: has been read */ 560: this_cmd, /* ... */ 561: last_cmd, /* last command ... to implement appending 562: to kill buffer */ 563: RecDepth, /* recursion depth */ 564: InputPending, /* nonzero if there is input waiting to 565: be processed */ 566: killptr, /* index into killbuf */ 567: CanScroll, /* can this terminal scroll? */ 568: Crashing, /* we are in the middle of crashing */ 569: Asking, /* are we on read a string from the terminal? */ 570: inIOread; /* so we know whether we can do a redisplay. */ 571: 572: extern char Minibuf[LBSIZE]; 573: 574: #define curmark (curbuf->b_markring[curbuf->b_themark]) 575: #define b_curmark(b) (b->b_markring[b->b_themark]) 576: 577: extern Line *killbuf[NUMKILLS]; /* array of pointers to killed stuff */ 578: 579: #define MESG_SIZE 128 580: extern char mesgbuf[MESG_SIZE]; 581: 582: struct screenline { 583: char *s_line, 584: *s_length; 585: }; 586: 587: extern int 588: LastKeyStruck; 589: 590: extern int 591: InMacDefine, /* are we defining a macro right now? */ 592: 593: CapLine, /* cursor line and cursor column */ 594: CapCol, 595: 596: UpdModLine, /* whether we want to update the mode line */ 597: UpdMesg; /* update the message line */ 598: 599: #define CATCH \ 600: {\ 601: jmp_buf sav_jmp; \ 602: \ 603: push_env(sav_jmp); \ 604: if (setjmp(mainjmp) == 0) { 605: 606: #define ONERROR \ 607: } else { \ 608: 609: #define ENDCATCH \ 610: } \ 611: pop_env(sav_jmp); \ 612: } 613: 614: #include "externs.h" 615: 616: 617: #define dispatch(c) \ 618: { \ 619: register data_obj *cp; \ 620: \ 621: this_cmd = 0; \ 622: cp = mainmap[c & CHARMASK]; \ 623: \ 624: if (cp == 0) { \ 625: rbell(); \ 626: clr_arg_value(); \ 627: errormsg = NO; \ 628: message(NullStr); \ 629: } else \ 630: ExecCmd(cp); \ 631: }