allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (08/20/89)
Posting-number: Volume 8, Issue 10 Submitted-by: tony@cs.utexas.edu@wldrdg.UUCP (Tony Andrews) Archive-name: stevie3.68/part08 [By now, you will have noted that the archive-name is stevie3.68, but the editor is version 3.69. Oops. Tony sent an updated version out just before I started posting, and I got the version numbers scrambled. Anyone else wonder why I want to add version tracking to the archives? ++bsa] #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # porting.doc # source.doc # dos.c # dos.mk # minix.c # minix.mk # os2.c # os2.mk # tos.c # tos.mk # unix.c # unix.mk # This archive created: Sun Aug 13 11:46:17 1989 export PATH; PATH=/bin:$PATH echo shar: extracting "'porting.doc'" '(2368 characters)' if test -f 'porting.doc' then echo shar: will not over-write existing file "'porting.doc'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'porting.doc' X X Release Notes for STEVIE - Version 3.68 X X Atari ST Editor for VI Enthusiasts X X Porting X X X Tony Andrews X X 8/6/88 X X X Porting the editor is a relatively simple task. Most of the Xcode is pretty machine-independent. For each environment, there is Xa file of routines that perform various low-level operations that Xtend to vary a lot from one machine to another. Another file contains Xthe escape sequences to be used for each machine. X X The machine-dependent files currently used are: X Xtos.c: Atari ST running TOS Xunix.c: UNIX System V or BSD Xos2.c: Microsoft OS/2 Xdos.c: MS DOS 3.3 Xminix.c: Minix on the Atari ST X X X Each of these files are around 250 lines long and deal with Xlow-level issues like character I/O to the terminal, terminal Xinitialization, signal handling (if supported), cursor addressing, and Xso on. There are different tradeoffs to be made depending on the Xenvironment. For example, the UNIX and Minix versions buffer terminal Xoutput because of the relatively high overhead of system calls. A quick Xlook at the files will make it clear what needs to be done in a new Xenvironment. X X The file "env.h" contains macro definitions to customize the Xeditor for your particular environment. The macros there select the Xmachine/os, enable various optional features, etc. X X One of the options in env.h is whether to use the termcap Xroutines or hard-wired escape sequences. The hard-wired sequences, Xif used, are defined in term.h. The file term.c contains code to access Xthe termcap database, if enabled. Termcap is only supported by some of Xthe system-dependent files (unix.c and minix.c) but can be added easily Xto others, if needed. X X X The basic process for doing a new port is: X X 1. Come up with a macro name to use when ifdef'ing your system- X specific changes. Add a line to 'env.h' to define the macro X name you've chosen. X X 2. Look at the system-dependent files and copy the one that comes X closest to working on your system. Then modify your new file X as needed. X X 3. Look at term.h and edit the file appropriately adding a new X set of escape sequence definitions for your system. X X 4. Compile and debug the editor. X X X In most cases it should really be that simple. Other ports have Xbeen done for which I don't have the code, including the Amiga, and a XData General machine of some kind (in Australia). HE_HATES_THESE_CANS if test 2368 -ne "`wc -c < 'porting.doc'`" then echo shar: error transmitting "'porting.doc'" '(should have been 2368 characters)' fi fi # end of overwriting check echo shar: extracting "'source.doc'" '(3058 characters)' if test -f 'source.doc' then echo shar: will not over-write existing file "'source.doc'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'source.doc' X X Release Notes for STEVIE - Version 3.68 X X Source Notes X X Tony Andrews X X 8/6/89 X X XOverview X-------- X X This file provides a brief description of the source code for XStevie. The data structures are described later as well. For information Xspecific to porting the editor, see the file 'porting.doc'. This document Xis more relevant to people who want to hack on the editor apart from doing Xa simple port. X X Most of this document was written some time ago so a lot of the Xdiscussion centers on problems related to the Atari ST environment and Xcompilers. Most of this can be ignored for other systems. X X XCruft X----- X X Older versions of the editor used Henry Spencer's regular Xexpression library directly. The current version incorporates a modified Xversion of that same library. X X XData Structures X--------------- X X A brief discussion of the evolution of the data structures will Xdo much to clarify the code, and explain some of the strangeness you may Xsee. X X In the original version, the file was maintained in memory as a Xsimple contiguous buffer. References to positions in the file were simply Xcharacter pointers. Due to the obvious performance problems inherent in Xthis approach, I made the following changes. X X The file is now represented by a doubly linked list of 'line' Xstructures defined as follows: X Xstruct line { X struct line *prev, *next; /* previous and next lines */ X char *s; /* text for this line */ X int size; /* actual size of space at 's' */ X unsigned long num; /* line "number" */ X}; X XThe members of the line structure are: X Xprev - pointer to the structure for the prior line, or NULL for the X first line of the file X Xnext - like 'prev' but points to the next line X Xs - points to the contents of the line (null terminated) X Xsize - contains the size of the chunk of space pointed to by s. This X is used so we know when we can add text to a line without getting X more space. When we DO need more space, we always get a little X extra so we don't make so many calls to malloc. X Xnum - This is a pseudo line number that makes it easy to compare X positions within the file. Otherwise, we'd have to traverse X all the links to tell which line came first. X X X Since character pointers served to mark file positions in the Xoriginal, a similar data object was needed for the new data structures. XThis purpose is served by the 'lptr' structure which is defined as: X Xstruct lptr { X struct line *linep; /* line we're referencing */ X int index; /* position within that line */ X}; X XThe member 'linep' points to the 'line' structure for the line containing Xthe location of interest. The integer 'index' is the offset into the line Xdata (member 's') of the character to be referenced. X XThe following typedef's are more commonly used: X Xtypedef struct line LINE; Xtypedef struct lptr LPTR; X XMany operations that were trivial with character pointers had to be Ximplemented by functions to manipulate LPTR's. Most of these are in the Xfile 'ptrfunc.c'. There you'll find functions to increment, decrement, Xand compare LPTR's. HE_HATES_THESE_CANS if test 3058 -ne "`wc -c < 'source.doc'`" then echo shar: error transmitting "'source.doc'" '(should have been 3058 characters)' fi fi # end of overwriting check echo shar: extracting "'dos.c'" '(5098 characters)' if test -f 'dos.c' then echo shar: will not over-write existing file "'dos.c'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'dos.c' X/* $Header: /nw/tony/src/stevie/src/RCS/dos.c,v 1.7 89/07/11 21:22:01 tony Exp $ X * X * DOS System-dependent routines. X * X * System-specific code for MS-DOS. This has been tested with X * MSDOS 3.3 on an AT. Also, the console driver "nansi.sys" is X * required. X */ X X#include "stevie.h" X#include <stdio.h> X#include <dos.h> X#include <signal.h> X Xstatic char getswitch(); Xstatic void setswitch(); X X/* X * inchar() - get a character from the keyboard X */ Xint Xinchar() X{ X int c; X X got_int = FALSE; X X for (;;beep()) { /* loop until we get a valid character */ X X flushbuf(); /* flush any pending output */ X X switch (c = getch()) { X case 0x1e: X return K_CGRAVE; X case 0: /* special key */ X if (State != NORMAL) { X c = getch(); /* throw away next char */ X continue; /* and loop for another char */ X } X switch (c = getch()) { X case 0x50: X return K_DARROW; X case 0x48: X return K_UARROW; X case 0x4b: X return K_LARROW; X case 0x4d: X return K_RARROW; X case 0x52: X return K_INSERT; X case 0x47: X stuffin("1G"); X return -1; X case 0x4f: X stuffin("G"); X return -1; X case 0x51: X stuffin(mkstr(CTRL('F'))); X return -1; X case 0x49: X stuffin(mkstr(CTRL('B'))); X return -1; X /* X * Hard-code some useful function key macros. X */ X case 0x3b: /* F1 */ X stuffin(":N\n"); X return -1; X case 0x54: /* SF1 */ X stuffin(":N!\n"); X return -1; X case 0x3c: /* F2 */ X stuffin(":n\n"); X return -1; X case 0x55: /* SF2 */ X stuffin(":n!\n"); X return -1; X case 0x3d: /* F3 */ X stuffin(":e #\n"); X return -1; X case 0x3e: /* F4 */ X stuffin(":rew\n"); X return -1; X case 0x57: /* SF4 */ X stuffin(":rew!\n"); X return -1; X case 0x3f: /* F5 */ X stuffin("[["); X return -1; X case 0x40: /* F6 */ X stuffin("]]"); X return -1; X case 0x41: /* F7 - explain C declaration */ X stuffin("yyp^iexplain \033!!cdecl\n"); X return -1; X case 0x42: /* F8 - declare C variable */ X stuffin("yyp!!cdecl\n"); X return -1; X case 0x43: /* F9 */ X stuffin(":x\n"); X return -1; X case 0x44: /* F10 */ X stuffin(":help\n"); X return -1; X default: X break; X } X break; X X default: X return c; X } X } X} X X#define BSIZE 2048 Xstatic char outbuf[BSIZE]; Xstatic int bpos = 0; X Xvoid Xflushbuf() X{ X if (bpos != 0) X write(1, outbuf, bpos); X bpos = 0; X} X X/* X * Macro to output a character. Used within this file for speed. X */ X#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf() X X/* X * Function version for use outside this file. X */ Xvoid Xoutchar(c) Xchar c; X{ X outone(c); X} X X/* X * outstr(s) - write a string to the console X */ Xvoid Xoutstr(s) Xregister char *s; X{ X while (*s) { X outone(*s++); X } X} X Xvoid Xbeep() X{ X outone('\007'); X} X Xsleep(n) Xint n; X{ X /* X * Should do something reasonable here. X */ X} X Xvoid Xdelay() X{ X long l; X X flushbuf(); X /* X * Should do something better here... X */ X for (l=0; l < 5000 ;l++) X ; X} X Xvoid Xsig() X{ X signal(SIGINT, sig); X X got_int = TRUE; X} X Xstatic char schar; /* save original switch character */ X Xvoid Xwindinit() X{ X Columns = 80; X P(P_LI) = Rows = 25; X schar = getswitch(); X setswitch('/'); X X signal(SIGINT, sig); X} X Xvoid Xwindexit(r) Xint r; X{ X flushbuf(); X setswitch(schar); X exit(r); X} X Xvoid Xwindgoto(r, c) Xregister int r, c; X{ X r += 1; X c += 1; X X /* X * Check for overflow once, to save time. X */ X if (bpos + 8 >= BSIZE) X flushbuf(); X X outbuf[bpos++] = '\033'; X outbuf[bpos++] = '['; X if (r >= 10) X outbuf[bpos++] = r/10 + '0'; X outbuf[bpos++] = r%10 + '0'; X outbuf[bpos++] = ';'; X if (c >= 10) X outbuf[bpos++] = c/10 + '0'; X outbuf[bpos++] = c%10 + '0'; X outbuf[bpos++] = 'H'; X} X XFILE * Xfopenb(fname, mode) Xchar *fname; Xchar *mode; X{ X FILE *fopen(); X char modestr[16]; X X sprintf(modestr, "%sb", mode); X return fopen(fname, modestr); X} X Xstatic char Xgetswitch() X{ X union REGS inregs, outregs; X X inregs.h.ah = 0x37; X inregs.h.al = 0; X X intdos(&inregs, &outregs); X X return outregs.h.dl; X} X Xstatic void Xsetswitch(c) Xchar c; X{ X union REGS inregs, outregs; X X inregs.h.ah = 0x37; X inregs.h.al = 1; X inregs.h.dl = c; X X intdos(&inregs, &outregs); X} X X#define PSIZE 128 X X/* X * fixname(s) - fix up a dos name X * X * Takes a name like: X * X * \x\y\z\base.ext X * X * and trims 'base' to 8 characters, and 'ext' to 3. X */ Xchar * Xfixname(s) Xchar *s; X{ X char *strchr(), *strrchr(); X static char f[PSIZE]; X char base[32]; X char ext[32]; X char *p; X int i; X X strcpy(f, s); X X for (i=0; i < PSIZE ;i++) X if (f[i] == '/') X f[i] = '\\'; X X /* X * Split the name into directory, base, extension. X */ X if ((p = strrchr(f, '\\')) != NULL) { X strcpy(base, p+1); X p[1] = '\0'; X } else { X strcpy(base, f); X f[0] = '\0'; X } X X if ((p = strchr(base, '.')) != NULL) { X strcpy(ext, p+1); X *p = '\0'; X } else X ext[0] = '\0'; X X /* X * Trim the base name if necessary. X */ X if (strlen(base) > 8) X base[8] = '\0'; X X if (strlen(ext) > 3) X ext[3] = '\0'; X X /* X * Paste it all back together X */ X strcat(f, base); X strcat(f, "."); X strcat(f, ext); X X return f; X} X Xvoid Xdoshell(cmd) Xchar *cmd; X{ X if (cmd == NULL) X cmd = "command.com"; X X system(cmd); X wait_return(); X} HE_HATES_THESE_CANS if test 5098 -ne "`wc -c < 'dos.c'`" then echo shar: error transmitting "'dos.c'" '(should have been 5098 characters)' fi fi # end of overwriting check echo shar: extracting "'dos.mk'" '(1602 characters)' if test -f 'dos.mk' then echo shar: will not over-write existing file "'dos.mk'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'dos.mk' X# X# Makefile for DOS X# X# Microsoft make is brain-dead, so please bear with me. X# X X# X# Compact model lets us edit large files, but keep small model code X# XMODEL= /AC XCFLAGS = $(MODEL) X XMACH= dos.obj X XOBJ= alloc.obj \ X main.obj \ X cmdline.obj \ X edit.obj \ X fileio.obj \ X help.obj \ X hexchars.obj \ X linefunc.obj \ X mark.obj \ X misccmds.obj \ X normal.obj \ X ops.obj \ X param.obj \ X ptrfunc.obj \ X regexp.obj \ X regsub.obj \ X screen.obj \ X search.obj \ X undo.obj \ X version.obj \ X $(MACH) X Xall: stevie.exe X Xalloc.obj : alloc.c X cl -c $(CFLAGS) alloc.c X Xcmdline.obj : cmdline.c X cl -c $(CFLAGS) cmdline.c X Xedit.obj : edit.c X cl -c $(CFLAGS) edit.c X Xfileio.obj : fileio.c X cl -c $(CFLAGS) fileio.c X Xhelp.obj : help.c X cl -c $(CFLAGS) help.c X Xhexchars.obj : hexchars.c X cl -c $(CFLAGS) hexchars.c X Xlinefunc.obj : linefunc.c X cl -c $(CFLAGS) linefunc.c X Xmain.obj: main.c X cl -c $(CFLAGS) main.c X Xmark.obj : mark.c X cl -c $(CFLAGS) mark.c X Xmisccmds.obj : misccmds.c X cl -c $(CFLAGS) misccmds.c X Xnormal.obj : normal.c X cl -c $(CFLAGS) normal.c X Xops.obj : ops.c X cl -c $(CFLAGS) ops.c X Xparam.obj : param.c X cl -c $(CFLAGS) param.c X Xptrfunc.obj : ptrfunc.c X cl -c $(CFLAGS) ptrfunc.c X Xregexp.obj : regexp.c X cl -c $(CFLAGS) regexp.c X Xregsub.obj : regsub.c X cl -c $(CFLAGS) regsub.c X Xscreen.obj : screen.c X cl -c $(CFLAGS) screen.c X Xsearch.obj : search.c X cl -c $(CFLAGS) search.c X Xundo.obj : undo.c X cl -c $(CFLAGS) undo.c X Xversion.obj : version.c X cl -c $(CFLAGS) version.c X Xdos.obj : dos.c X cl -c $(CFLAGS) dos.c X Xstevie.exe : $(OBJ) X cl $(MODEL) *.obj c:\pmsdk\lib\setargv.obj -o stevie.exe /F 6000 -link /NOE HE_HATES_THESE_CANS if test 1602 -ne "`wc -c < 'dos.mk'`" then echo shar: error transmitting "'dos.mk'" '(should have been 1602 characters)' fi fi # end of overwriting check echo shar: extracting "'minix.c'" '(3129 characters)' if test -f 'minix.c' then echo shar: will not over-write existing file "'minix.c'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'minix.c' X/* $Header: /nw/tony/src/stevie/src/RCS/minix.c,v 1.5 89/07/11 21:24:18 tony Exp $ X * X * System-dependent routines for Minix-ST X */ X X#include "stevie.h" X#include <sgtty.h> X#include <signal.h> X X/* X * inchar() - get a character from the keyboard X */ Xint Xinchar() X{ X char c; X X flushbuf(); /* flush any pending output */ X X while (read(0, &c, 1) != 1) X ; X X got_int = FALSE; X return c; X} X X#define BSIZE 2048 Xstatic char outbuf[BSIZE]; Xstatic int bpos = 0; X Xvoid Xflushbuf() X{ X if (bpos != 0) X write(1, outbuf, bpos); X bpos = 0; X} X X/* X * Macro to output a character. Used within this file for speed. X */ X#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf() X X/* X * Function version for use outside this file. X */ Xvoid Xoutchar(c) Xregister char c; X{ X outbuf[bpos++] = c; X if (bpos >= BSIZE) X flushbuf(); X} X Xvoid Xoutstr(s) Xregister char *s; X{ X while (*s) { X outone(*s++); X } X} X Xvoid Xbeep() X{ X outone('\007'); X} X X/* X * remove(file) - remove a file X */ Xvoid Xremove(file) Xchar *file; X{ X unlink(file); X} X X/* X * rename(of, nf) - rename existing file 'of' to 'nf' X */ Xvoid Xrename(of, nf) Xchar *of, *nf; X{ X unlink(nf); X link(of, nf); X unlink(of); X} X Xvoid Xdelay() X{ X /* not implemented */ X} X Xstatic struct sgttyb ostate; X X/* X * Go into cbreak mode X */ Xvoid Xset_tty() X{ X struct sgttyb nstate; X X ioctl(0, TIOCGETP, &ostate); X nstate = ostate; X nstate.sg_flags &= ~(XTABS|ECHO); X nstate.sg_flags |= CBREAK; X ioctl(0, TIOCSETP, &nstate); X} X X/* X * Restore original terminal modes X */ Xvoid Xreset_tty() X{ X ioctl(0, TIOCSETP, &ostate); X} X Xvoid Xsig() X{ X signal(SIGINT, sig); X signal(SIGQUIT, sig); X X got_int = TRUE; X} X Xvoid Xwindinit() X{ X#ifdef TERMCAP X if (t_init() != 1) { X fprintf(stderr, "unknown terminal type\n"); X exit(1); X } X#else X Columns = 80; X P(P_LI) = Rows = 25; X#endif X /* X * The code here makes sure that there isn't a window during which X * we could get interrupted and exit with the tty in a weird state. X */ X signal(SIGINT, sig); X signal(SIGQUIT, sig); X X set_tty(); X X if (got_int) X windexit(0); X} X Xvoid Xwindexit(r) Xint r; X{ X reset_tty(); X exit(r); X} X Xvoid Xwindgoto(r, c) Xregister int r, c; X{ X#ifdef TERMCAP X char *tgoto(); X#else X r += 1; X c += 1; X#endif X X /* X * Check for overflow once, to save time. X */ X if (bpos + 8 >= BSIZE) X flushbuf(); X X#ifdef TERMCAP X outstr(tgoto(T_CM, c, r)); X#else X outbuf[bpos++] = '\033'; X outbuf[bpos++] = '['; X if (r >= 10) X outbuf[bpos++] = r/10 + '0'; X outbuf[bpos++] = r%10 + '0'; X outbuf[bpos++] = ';'; X if (c >= 10) X outbuf[bpos++] = c/10 + '0'; X outbuf[bpos++] = c%10 + '0'; X outbuf[bpos++] = 'H'; X#endif X} X XFILE * Xfopenb(fname, mode) Xchar *fname; Xchar *mode; X{ X return fopen(fname, mode); X} X Xchar * Xstrchr(s, c) Xchar *s; Xchar c; X{ X char *index(); X X return index(s, c); X} X Xchar * Xfixname(s) Xchar *s; X{ X return s; X} X X/* X * doshell() - run a command or an interactive shell X */ Xvoid Xdoshell(cmd) Xchar *cmd; X{ X char *cp, *getenv(); X char cline[128]; X X outstr("\r\n"); X flushbuf(); X X if (cmd == NULL) { X if ((cmd = getenv("SHELL")) == NULL) X cmd = "/bin/sh"; X sprintf(cline, "%s -i", cmd); X cmd = cline; X } X X reset_tty(); X system(cmd); X set_tty(); X X wait_return(); X} HE_HATES_THESE_CANS if test 3129 -ne "`wc -c < 'minix.c'`" then echo shar: error transmitting "'minix.c'" '(should have been 3129 characters)' fi fi # end of overwriting check echo shar: extracting "'minix.mk'" '(449 characters)' if test -f 'minix.mk' then echo shar: will not over-write existing file "'minix.mk'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'minix.mk' X# X# Makefile for Atari ST Minix X# X XLDFLAGS= XCFLAGS= -O X XMACH= minix.o X XOBJ= alloc.o \ X cmdline.o \ X edit.o \ X fileio.o \ X help.o \ X hexchars.o \ X linefunc.o \ X main.o \ X mark.o \ X misccmds.o \ X normal.o \ X ops.o \ X param.o \ X ptrfunc.o \ X regexp.o \ X regsub.o \ X screen.o \ X search.o \ X term.o \ X undo.o \ X version.o X Xall : stevie X Xstevie : $(OBJ) $(MACH) X $(CC) $(LDFLAGS) $(OBJ) $(MACH) -o stevie X chmem =150000 stevie X Xclean : X rm $(OBJ) $(MACH) HE_HATES_THESE_CANS if test 449 -ne "`wc -c < 'minix.mk'`" then echo shar: error transmitting "'minix.mk'" '(should have been 449 characters)' fi fi # end of overwriting check echo shar: extracting "'os2.c'" '(4931 characters)' if test -f 'os2.c' then echo shar: will not over-write existing file "'os2.c'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'os2.c' X/* $Header: /nw/tony/src/stevie/src/RCS/os2.c,v 1.7 89/08/07 05:49:19 tony Exp $ X * X * OS/2 System-dependent routines. X */ X X#define INCL_BASE X#include <os2.h> X#include <signal.h> X#include "stevie.h" X X/* X * inchar() - get a character from the keyboard X */ Xint Xinchar() X{ X register int c; X X got_int = FALSE; X X for (;;beep()) { /* loop until we get a valid character */ X X flushbuf(); /* flush any pending output */ X X switch (c = getch()) { X case 0x1e: X return K_CGRAVE; X case 0: /* special key */ X if (State != NORMAL) { X c = getch(); /* throw away next char */ X continue; /* and loop for another char */ X } X switch (c = getch()) { X case 0x50: X return K_DARROW; X case 0x48: X return K_UARROW; X case 0x4b: X return K_LARROW; X case 0x4d: X return K_RARROW; X case 0x52: X return K_INSERT; X case 0x47: X stuffin("1G"); X return -1; X case 0x4f: X stuffin("G"); X return -1; X case 0x51: X stuffin(mkstr(CTRL('F'))); X return -1; X case 0x49: X stuffin(mkstr(CTRL('B'))); X return -1; X /* X * Hard-code some useful function key macros. X */ X case 0x3b: /* F1 */ X stuffin(":N\n"); X return -1; X case 0x54: /* SF1 */ X stuffin(":N!\n"); X return -1; X case 0x3c: /* F2 */ X stuffin(":n\n"); X return -1; X case 0x55: /* SF2 */ X stuffin(":n!\n"); X return -1; X case 0x3d: /* F3 */ X stuffin(":e #\n"); X return -1; X case 0x3e: /* F4 */ X stuffin(":rew\n"); X return -1; X case 0x57: /* SF4 */ X stuffin(":rew!\n"); X return -1; X case 0x3f: /* F5 */ X stuffin("[["); X return -1; X case 0x40: /* F6 */ X stuffin("]]"); X return -1; X case 0x41: /* F7 - explain C declaration */ X stuffin("yyp^iexplain \033!!cdecl\n"); X return -1; X case 0x42: /* F8 - declare C variable */ X stuffin("yyp!!cdecl\n"); X return -1; X case 0x43: /* F9 */ X stuffin(":x\n"); X return -1; X case 0x44: /* F10 */ X stuffin(":help\n"); X return -1; X default: X break; X } X break; X X default: X return c; X } X } X} X X#define BSIZE 2048 Xstatic char outbuf[BSIZE]; Xstatic int bpos = 0; X Xvoid Xflushbuf() X{ X if (bpos != 0) X write(1, outbuf, bpos); X bpos = 0; X} X X/* X * Macro to output a character. Used within this file for speed. X */ X#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf() X X/* X * Function version for use outside this file. X */ Xvoid Xoutchar(c) Xregister char c; X{ X outbuf[bpos++] = c; X if (bpos >= BSIZE) X flushbuf(); X} X Xstatic char cell[2] = { 0, 7 }; X X/* X * outstr(s) - write a string to the console X * X * We implement insert/delete line escape sequences here. This is kind X * of a kludge, but at least it's localized to a single point. X */ Xvoid Xoutstr(s) Xregister char *s; X{ X if (strcmp(s, T_DL) == 0) { /* delete line */ X int r, c; X X flushbuf(); X VioGetCurPos(&r, &c, 0); X VioScrollUp(r, 0, 100, 100, 1, cell, 0); X return; X } X if (strcmp(s, T_IL) == 0) { /* insert line */ X int r, c; X X flushbuf(); X VioGetCurPos(&r, &c, 0); X VioScrollDn(r, 0, 100, 100, 1, cell, 0); X return; X } X X while (*s) { X outone(*s++); X } X} X Xvoid Xbeep() X{ X outone('\007'); X} X Xsleep(n) Xint n; X{ X DosSleep(1000L * n); X} X Xvoid Xdelay() X{ X flushbuf(); X DosSleep(300L); X} X Xvoid Xsig() X{ X signal(SIGINT, sig); X X got_int = TRUE; X} X Xvoid Xwindinit() X{ X Columns = 80; X P(P_LI) = Rows = 25; X X signal(SIGINT, sig); X} X Xvoid Xwindexit(r) Xint r; X{ X flushbuf(); X exit(r); X} X Xvoid Xwindgoto(r, c) Xregister int r, c; X{ X r += 1; X c += 1; X X /* X * Check for overflow once, to save time. X */ X if (bpos + 8 >= BSIZE) X flushbuf(); X X outbuf[bpos++] = '\033'; X outbuf[bpos++] = '['; X if (r >= 10) X outbuf[bpos++] = r/10 + '0'; X outbuf[bpos++] = r%10 + '0'; X outbuf[bpos++] = ';'; X if (c >= 10) X outbuf[bpos++] = c/10 + '0'; X outbuf[bpos++] = c%10 + '0'; X outbuf[bpos++] = 'H'; X} X XFILE * Xfopenb(fname, mode) Xchar *fname; Xchar *mode; X{ X FILE *fopen(); X char modestr[16]; X X sprintf(modestr, "%sb", mode); X return fopen(fname, modestr); X} X X#define PSIZE 128 X X/* X * fixname(s) - fix up a dos name X * X * Takes a name like: X * X * \x\y\z\base.ext X * X * and trims 'base' to 8 characters, and 'ext' to 3. X */ Xchar * Xfixname(s) Xchar *s; X{ X char *strchr(), *strrchr(); X static char f[PSIZE]; X char base[32]; X char ext[32]; X char *p; X int i; X X strcpy(f, s); X X for (i=0; i < PSIZE ;i++) X if (f[i] == '/') X f[i] = '\\'; X X /* X * Split the name into directory, base, extension. X */ X if ((p = strrchr(f, '\\')) != NULL) { X strcpy(base, p+1); X p[1] = '\0'; X } else { X strcpy(base, f); X f[0] = '\0'; X } X X if ((p = strchr(base, '.')) != NULL) { X strcpy(ext, p+1); X *p = '\0'; X } else X ext[0] = '\0'; X X /* X * Trim the base name if necessary. X */ X if (strlen(base) > 8) X base[8] = '\0'; X X if (strlen(ext) > 3) X ext[3] = '\0'; X X /* X * Paste it all back together X */ X strcat(f, base); X strcat(f, "."); X strcat(f, ext); X X return f; X} X Xvoid Xdoshell(cmd) Xchar *cmd; X{ X if (cmd == NULL) X cmd = "cmd.exe"; X X system(cmd); X wait_return(); X} HE_HATES_THESE_CANS if test 4931 -ne "`wc -c < 'os2.c'`" then echo shar: error transmitting "'os2.c'" '(should have been 4931 characters)' fi fi # end of overwriting check echo shar: extracting "'os2.mk'" '(1547 characters)' if test -f 'os2.mk' then echo shar: will not over-write existing file "'os2.mk'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'os2.mk' X# X# Makefile for OS/2 X# X# The make command with OS/2 is really stupid. X# X X# X# Compact model lets us edit large files, but keep small model code X# XMODEL= /AC XCFLAGS = $(MODEL) X XMACH= os2.obj X XOBJ= alloc.obj \ X cmdline.obj \ X edit.obj \ X fileio.obj \ X help.obj \ X hexchars.obj \ X linefunc.obj \ X main.obj \ X mark.obj \ X misccmds.obj \ X normal.obj \ X ops.obj \ X param.obj \ X ptrfunc.obj \ X screen.obj \ X search.obj \ X undo.obj \ X version.obj \ X $(MACH) X Xalloc.obj : alloc.c X cl -c $(CFLAGS) alloc.c X Xcmdline.obj : cmdline.c X cl -c $(CFLAGS) cmdline.c X Xedit.obj : edit.c X cl -c $(CFLAGS) edit.c X Xfileio.obj : fileio.c X cl -c $(CFLAGS) fileio.c X Xhexchars.obj : hexchars.c X cl -c $(CFLAGS) hexchars.c X Xlinefunc.obj : linefunc.c X cl -c $(CFLAGS) linefunc.c X Xmain.obj: main.c X cl -c $(CFLAGS) main.c X Xmark.obj : mark.c X cl -c $(CFLAGS) mark.c X Xmisccmds.obj : misccmds.c X cl -c $(CFLAGS) misccmds.c X Xnormal.obj : normal.c X cl -c $(CFLAGS) normal.c X Xhelp.obj : help.c X cl -c $(CFLAGS) help.c X Xops.obj : ops.c X cl -c $(CFLAGS) ops.c X Xparam.obj : param.c X cl -c $(CFLAGS) param.c X Xptrfunc.obj : ptrfunc.c X cl -c $(CFLAGS) ptrfunc.c X Xregexp.obj : regexp.c X cl -c $(CFLAGS) regexp.c X Xregsub.obj : regsub.c X cl -c $(CFLAGS) regsub.c X Xscreen.obj : screen.c X cl -c $(CFLAGS) screen.c X Xsearch.obj : search.c X cl -c $(CFLAGS) search.c X Xundo.obj : undo.c X cl -c $(CFLAGS) undo.c X Xversion.obj : version.c X cl -c $(CFLAGS) version.c X Xos2.obj : os2.c X cl -c $(CFLAGS) os2.c X Xstevie.exe : $(OBJ) X cl $(MODEL) *.obj \pmsdk\lib\setargv.obj -o stevie.exe /F 6000 -link /NOE HE_HATES_THESE_CANS if test 1547 -ne "`wc -c < 'os2.mk'`" then echo shar: error transmitting "'os2.mk'" '(should have been 1547 characters)' fi fi # end of overwriting check echo shar: extracting "'tos.c'" '(5474 characters)' if test -f 'tos.c' then echo shar: will not over-write existing file "'tos.c'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'tos.c' X/* $Header: /nw/tony/src/stevie/src/RCS/tos.c,v 1.5 89/07/13 22:45:31 tony Exp $ X * X * System-dependent routines for the Atari ST. X */ X X#include "stevie.h" X X#include <osbind.h> X X/* X * inchar() - get a character from the keyboard X * X * Certain special keys are mapped to values above 0x80. These X * mappings are defined in keymap.h. If the key has a non-zero X * ascii value, it is simply returned. Otherwise it may be a X * special key we want to map. X * X * The ST has a bug involving keyboard input that seems to occur X * when typing quickly, especially typing capital letters. Sometimes X * a value of 0x02540000 is read. This doesn't correspond to anything X * on the keyboard, according to my documentation. My solution is to X * loop when any unknown key is seen. Normally, the bell is rung to X * indicate the error. If the "bug" value is seen, we ignore it completely. X */ Xint Xinchar() X{ X register long c; X X for (;;) { X c = Bconin(2); X X if ((c & 0xff) != 0) X return ((int) c); X X switch ((int) (c >> 16) & 0xff) { X X case 0x62: return K_HELP; X case 0x61: return K_UNDO; X case 0x52: return K_INSERT; X case 0x47: return K_HOME; X case 0x48: return K_UARROW; X case 0x50: return K_DARROW; X case 0x4b: return K_LARROW; X case 0x4d: return K_RARROW; X case 0x29: return K_CGRAVE; /* control grave accent */ X X /* X * Occurs due to a bug in TOS. X */ X case 0x54: X break; X /* X * Add the function keys here later if we put in support X * for macros. X */ X X default: X beep(); X break; X X } X } X} X Xvoid Xoutchar(c) Xchar c; X{ X if (c < ' ') X Bconout(2, c); X else X Bconout(5, c); X} X Xvoid Xoutstr(s) Xregister char *s; X{ X while (*s) X Bconout(2, *s++); X} X X/* X * flushbuf() - a no-op for TOS X */ Xvoid Xflushbuf() X{ X} X X#define BGND 0 X#define TEXT 3 X X/* X * vbeep() - visual bell X */ Xstatic void Xvbeep() X{ X int text, bgnd; /* text and background colors */ X long l; X X text = Setcolor(TEXT, -1); X bgnd = Setcolor(BGND, -1); X X Setcolor(TEXT, bgnd); /* swap colors */ X Setcolor(BGND, text); X X for (l=0; l < 5000 ;l++) /* short pause */ X ; X X Setcolor(TEXT, text); /* restore colors */ X Setcolor(BGND, bgnd); X} X Xvoid Xbeep() X{ X if (P(P_VB)) X vbeep(); X else X outchar('\007'); X} X X/* X * remove(file) - remove a file X */ Xvoid Xremove(file) Xchar *file; X{ X Fdelete(file); X} X X/* X * rename(of, nf) - rename existing file 'of' to 'nf' X */ Xvoid Xrename(of, nf) Xchar *of, *nf; X{ X Fdelete(nf); /* if 'nf' exists, remove it */ X Frename(0, of, nf); X} X Xvoid Xwindinit() X{ X if (Getrez() == 0) X Columns = 40; /* low resolution */ X else X Columns = 80; /* medium or high */ X X P(P_LI) = Rows = 25; X X Cursconf(1,NULL); X} X Xvoid Xwindexit(r) Xint r; X{ X exit(r); X} X Xstatic char gobuf[5] = { '\033', 'Y', '\0', '\0', '\0' }; X Xvoid Xwindgoto(r, c) Xint r, c; X{ X gobuf[2] = r + 040; X gobuf[3] = c + 040; X outstr(gobuf); X} X X/* X * System calls or library routines missing in TOS. X */ X Xvoid Xsleep(n) Xint n; X{ X int k; X X k = Tgettime(); X while ( Tgettime() <= k+n ) X ; X} X Xvoid Xdelay() X{ X long n; X X for (n = 0; n < 8000 ;n++) X ; X} X Xint Xsystem(cmd) Xchar *cmd; X{ X char arg[1]; X X arg[0] = (char) 0; /* no arguments passed to the shell */ X X if (Pexec(0, cmd, arg, 0L) < 0) X return -1; X else X return 0; X} X X#ifdef SOZOBON X XFILE * Xfopenb(fname, mode) Xchar *fname; Xchar *mode; X{ X char modestr[10]; X X sprintf(modestr, "%sb", mode); X X return fopen(fname, modestr); X} X X#endif X X#ifndef SOZOBON X/* X * getenv() - get a string from the environment X * X * Both Alcyon and Megamax are missing getenv(). This routine works for X * both compilers and with the Beckemeyer and Gulam shells. With gulam, X * the env_style variable should be set to either "mw" or "gu". X */ Xchar * Xgetenv(name) Xchar *name; X{ X extern long _base; X char *envp, *p; X X envp = *((char **) (_base + 0x2c)); X X for (; *envp ;envp += strlen(envp)+1) { X if (strncmp(envp, name, strlen(name)) == 0) { X p = envp + strlen(name); X if (*p++ == '=') X return p; X } X } X return (char *) 0; X} X#endif X X/* X * mktemp() - quick hack since there isn't one here X */ Xchar * Xmktemp(name) Xchar *name; X{ X int num; /* pasted into the string to make it unique */ X char cbuf[7]; X char *s; /* where the X's start in name */ X int fd; X X if ((s = strchr(name, 'X')) == NULL) /* needs to be an X */ X return (char *) NULL; X X if (strlen(s) != 6) /* should be 6 X's */ X return (char *) NULL; X X for (num = 0; num < 1000 ;num++) { X sprintf(cbuf, "%06d", num); X strcpy(s, cbuf); X if ((fd = open(name, 0)) < 0) X return name; X close(fd); X } X return (char *) NULL; X} X Xvoid Xdoshell(cmd) Xchar *cmd; X{ X if (cmd == NULL) { X shell(); X return; X } X system(cmd); X wait_return(); X} X X#define PSIZE 128 X X/* X * fixname(s) - fix up a dos name X * X * Takes a name like: X * X * \x\y\z\base.ext X * X * and trims 'base' to 8 characters, and 'ext' to 3. X */ Xchar * Xfixname(s) Xchar *s; X{ X char *strchr(), *strrchr(); X static char f[PSIZE]; X char base[32]; X char ext[32]; X char *p; X int i; X X strcpy(f, s); X X for (i=0; i < PSIZE ;i++) X if (f[i] == '/') X f[i] = '\\'; X X /* X * Split the name into directory, base, extension. X */ X if ((p = strrchr(f, '\\')) != NULL) { X strcpy(base, p+1); X p[1] = '\0'; X } else { X strcpy(base, f); X f[0] = '\0'; X } X X if ((p = strchr(base, '.')) != NULL) { X strcpy(ext, p+1); X *p = '\0'; X } else X ext[0] = '\0'; X X /* X * Trim the base name if necessary. X */ X if (strlen(base) > 8) X base[8] = '\0'; X X if (strlen(ext) > 3) X ext[3] = '\0'; X X /* X * Paste it all back together X */ X strcat(f, base); X strcat(f, "."); X strcat(f, ext); X X return f; X} HE_HATES_THESE_CANS if test 5474 -ne "`wc -c < 'tos.c'`" then echo shar: error transmitting "'tos.c'" '(should have been 5474 characters)' fi fi # end of overwriting check echo shar: extracting "'tos.mk'" '(475 characters)' if test -f 'tos.mk' then echo shar: will not over-write existing file "'tos.mk'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'tos.mk' X# X# Makefile for the Atari ST - Sozobon C Compiler X# X XCFLAGS = -O X X.c.o: X $(CC) -c $(CFLAGS) $< X ar rv vi.lib $*.o X XMACH = tos.o X XOBJ = alloc.o \ X cmdline.o \ X edit.o \ X fileio.o \ X help.o \ X hexchars.o \ X linefunc.o \ X main.o \ X mark.o \ X misccmds.o \ X normal.o \ X ops.o \ X param.o \ X ptrfunc.o \ X regexp.o \ X regsub.o \ X screen.o \ X search.o \ X undo.o \ X version.o \ X $(MACH) X Xall : stevie.ttp X Xstevie.ttp : $(OBJ) X $(CC) vi.lib -o stevie.ttp X Xclean : X $(RM) $(OBJ) vi.lib HE_HATES_THESE_CANS if test 475 -ne "`wc -c < 'tos.mk'`" then echo shar: error transmitting "'tos.mk'" '(should have been 475 characters)' fi fi # end of overwriting check echo shar: extracting "'unix.c'" '(3416 characters)' if test -f 'unix.c' then echo shar: will not over-write existing file "'unix.c'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'unix.c' X/* $Header: /nw/tony/src/stevie/src/RCS/unix.c,v 1.8 89/08/06 09:51:13 tony Exp $ X * X * System-dependent routines for UNIX System V or Berkeley. X */ X X#include "stevie.h" X#ifdef BSD X#include <sgtty.h> X#else X#include <termio.h> X#endif X#include <signal.h> X X/* X * inchar() - get a character from the keyboard X */ Xint Xinchar() X{ X char c; X X flushbuf(); /* flush any pending output */ X X do { X while (read(0, &c, 1) != 1) X ; X } while (c == NUL); X X got_int = FALSE; X return c; X} X X#define BSIZE 2048 Xstatic char outbuf[BSIZE]; Xstatic int bpos = 0; X Xvoid Xflushbuf() X{ X if (bpos != 0) X write(1, outbuf, bpos); X bpos = 0; X} X X/* X * Macro to output a character. Used within this file for speed. X */ X#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf() X X/* X * Function version for use outside this file. X */ Xvoid Xoutchar(c) Xchar c; X{ X outone(c); X} X Xvoid Xoutstr(s) Xregister char *s; X{ X while (*s) { X outone(*s++); X } X} X Xvoid Xbeep() X{ X outone('\007'); X} X X/* X * remove(file) - remove a file X */ Xvoid Xremove(file) Xchar *file; X{ X unlink(file); X} X X/* X * rename(of, nf) - rename existing file 'of' to 'nf' X */ Xvoid Xrename(of, nf) Xchar *of, *nf; X{ X unlink(nf); X link(of, nf); X unlink(of); X} X Xvoid Xdelay() X{ X /* not implemented */ X} X X#ifdef BSD Xstatic struct sgttyb ostate; X#else Xstatic struct termio ostate; X#endif X X/* X * Go into cbreak mode X */ Xvoid Xset_tty() X{ X#ifdef BSD X struct sgttyb nstate; X X ioctl(0, TIOCGETP, &ostate); X nstate = ostate; X nstate.sg_flags &= ~(XTABS|CRMOD|ECHO); X nstate.sg_flags |= CBREAK; X ioctl(0, TIOCSETN, &nstate); X#else X struct termio nstate; X X ioctl(0, TCGETA, &ostate); X nstate = ostate; X nstate.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); X nstate.c_cc[VMIN] = 1; X nstate.c_cc[VTIME] = 0; X ioctl(0, TCSETAW, &nstate); X#endif X} X X/* X * Restore original terminal modes X */ Xvoid Xreset_tty() X{ X#ifdef BSD X ioctl(0, TIOCSETP, &ostate); X#else X ioctl(0, TCSETAW, &ostate); X#endif X} X Xvoid Xsig() X{ X signal(SIGINT, sig); X signal(SIGQUIT, sig); X X got_int = TRUE; X} X Xvoid Xwindinit() X{ X#ifdef TERMCAP X if (t_init() != 1) { X fprintf(stderr, "unknown terminal type\n"); X exit(1); X } X#else X Columns = 80; X P(P_LI) = Rows = 24; X#endif X X /* X * The code here makes sure that there isn't a window during which X * we could get interrupted and exit with the tty in a weird state. X */ X signal(SIGINT, sig); X signal(SIGQUIT, sig); X X set_tty(); X X if (got_int) X windexit(0); X} X Xvoid Xwindexit(r) Xint r; X{ X reset_tty(); X exit(r); X} X Xvoid Xwindgoto(r, c) Xregister int r, c; X{ X#ifdef TERMCAP X char *tgoto(); X#else X r += 1; X c += 1; X#endif X X /* X * Check for overflow once, to save time. X */ X if (bpos + 8 >= BSIZE) X flushbuf(); X X#ifdef TERMCAP X outstr(tgoto(T_CM, c, r)); X#else X outbuf[bpos++] = '\033'; X outbuf[bpos++] = '['; X if (r >= 10) X outbuf[bpos++] = r/10 + '0'; X outbuf[bpos++] = r%10 + '0'; X outbuf[bpos++] = ';'; X if (c >= 10) X outbuf[bpos++] = c/10 + '0'; X outbuf[bpos++] = c%10 + '0'; X outbuf[bpos++] = 'H'; X#endif X} X XFILE * Xfopenb(fname, mode) Xchar *fname; Xchar *mode; X{ X return fopen(fname, mode); X} X Xchar * Xfixname(s) Xchar *s; X{ X return s; X} X X/* X * doshell() - run a command or an interactive shell X */ Xvoid Xdoshell(cmd) Xchar *cmd; X{ X char *getenv(); X char cline[128]; X X outstr("\r\n"); X flushbuf(); X X if (cmd == NULL) { X if ((cmd = getenv("SHELL")) == NULL) X cmd = "/bin/sh"; X sprintf(cline, "%s -i", cmd); X cmd = cline; X } X X reset_tty(); X system(cmd); X set_tty(); X X wait_return(); X} HE_HATES_THESE_CANS if test 3416 -ne "`wc -c < 'unix.c'`" then echo shar: error transmitting "'unix.c'" '(should have been 3416 characters)' fi fi # end of overwriting check echo shar: extracting "'unix.mk'" '(787 characters)' if test -f 'unix.mk' then echo shar: will not over-write existing file "'unix.mk'" else sed 's/^X//' << \HE_HATES_THESE_CANS > 'unix.mk' X# X# Makefile for UNIX (System V) X# X XLDFLAGS= XCFLAGS= -g X XH= ascii.h \ X env.h \ X keymap.h \ X ops.h \ X param.h \ X regexp.h \ X regmagic.h \ X stevie.h \ X term.h X XMACH= unix.o X XOBJ= alloc.o \ X cmdline.o \ X edit.o \ X fileio.o \ X help.o \ X hexchars.o \ X linefunc.o \ X main.o \ X mark.o \ X misccmds.o \ X normal.o \ X ops.o \ X param.o \ X ptrfunc.o \ X regexp.o \ X regsub.o \ X screen.o \ X search.o \ X term.o \ X undo.o \ X version.o X XSRC= $(OBJ:.o=.c) $(MACH:.o=.c) X Xall : stevie stevie.doc X Xstevie : $(OBJ) $(MACH) X $(CC) $(LDFLAGS) $(OBJ) $(MACH) -o stevie -lcurses X Xlint : X lint $(SRC) X Xtags : X ctags $(SRC) $(H) X Xstevie.doc : stevie.mm X nroff -rB1 -Tlp -mm stevie.mm > stevie.doc X Xprint : X @pr $(H) $(SRC) X Xcflow : X cflow $(SRC) > cflow.for X cflow -r $(SRC) > cflow.rev X Xclean : X rm $(OBJ) $(MACH) HE_HATES_THESE_CANS if test 787 -ne "`wc -c < 'unix.mk'`" then echo shar: error transmitting "'unix.mk'" '(should have been 787 characters)' fi fi # end of overwriting check # End of shell archive exit 0 --