Article View: comp.editors
Article #2723Simple Editor (IOCCC '91 Entry)
From: Anthony Howe
Date: Thu, 30 May 1991 13:09
Date: Thu, 30 May 1991 13:09
196 lines
8047 bytes
8047 bytes
I've been iching to post this for over a year now to this group,
but had to wait till after the closing of entries for the
International Obfuscated C Code Contest for this year. This code
may or may not win, but it should prove interesting.
What you'll find below is my simple VI-like full screen editor.
Now before I get caught in the cross-fire of the VI vs Emacs war,
remember that the *source* code has to be less than 1.5k or 1536
bytes to enter the IOCCC. The use of modes and VI-like keys made
the code all that much smaller allowing me to add more commands
like word movement. With a little careful unwrapping of the
source, it should be *very* easy to configure the program to use
CURSES' keypad(1) function and the KEY_xxxx macros to obtain use
of all your favourite terminal function keys. I had experimental
versions that did this.
This code should also prove interesting since I use the Buffer Gap
scheme that was discussed in the this group in the Editor 101 and
102 articles.
All entries into the IOCCC must be in the public domain and so
this means you can do what you like to it. Below is the entry
exactly as I sent it off. You'll have to cut out the man page
which follows the remarks: line and also cut out the source.
Note that the leading X's in the source are part of the entry
form not the code.
---header items---
name: Anthony C Howe
org: Mortice Kern Systems Inc.
35 King St. N, Waterloo, On, Canada, N2J 2W9
email address: ant@mks.com or ..!watmath!mks!ant
postal address: #CL-23, 268 Phillip St, Waterloo, On, Canada, N2L 6G9
environment: Interactive UNIX System V/386 Release 3.2
BSD Unix 4.3
Atari Mega ST using Sozobon C
NEC Ultralite using WatCom C v7
Some PC 386 box using Turbo C v1.5
entry: 0
remarks:
NAME
ae Ant's Editor vIOCCC91
USAGE
ae <filename>
where <filename> is the text file to edit or create.
DESCRIPTION
<< ae >> is a full screen, VI style text editor. The source
should be portable to any environment that provides a K&R C
compiler and a CURSES library. (Even EBCDIC machines provided
the above two requirements are met.)
Text files consists of lines of printable text or tab characters.
A line can be of arbitary length and is delimited by either a
newline or the end of file. Carriage return is mapped to newline
on input and ignored on output. Tab stops are every eight columns.
Non-printable characters may have unpredictable results depending
on the implementation of CURSES.
COMMANDS
h j k l left, down, up, right cursor movement
H J K L word left, page down, page up, word right
[ ] beginning and end of line
t b top and bottom of file
i enter insert mode, formfeed to quit
x delete character under the cursor
W write buffer to file
R refresh the screen
Q quit
EXIT STATUS
0 success
2 missing edit filename
INSTALLATION
Requires K&R C and a CURSES library for the given target machine.
The file creation MODE should be set at compile time to 0600 for
Unix systems, or 0 for the Atari ST and PC.
The BUF size should be set at compile time to 32767. This value
was used because the Sozobon C compiler for the Atari ST has 16
bit ints and a limit on the size of arrays & structures of 32k.
Also the WatCom C compiler for the PC also has 16 bits ints. On
machines that have 32 bit ints (most unix boxes), a larger value
for BUF could be used.
It is recommend that compact memory model be used on PC class
machines. Small memory model may work too provided BUF is not
too large.
The character constants '\b', '\f', '\n', '\r', '\t' are used
in order to provide more portable code, since the compiler should
handle the translation of them into the native character set.
Note that '\f' (formfeed) was used to exit insert mode because
K&R C had no escape constant for the escape-key.
Note that the "int " definition at the top of the source was for
the benifit of Turbo C, which returns lots of warnings. WatCom C
should return no warnings provided your curses.h has no NULL
expression defined for functions. System V and BSD should also
generate no warnings. The source should pass basic linting.
The source still looks like a mess when passed through our
C beautifier (your milleage may vary).
My goals for this project were to learn and experiment with the
Buffer Gap Scheme [Fin80][net90], write a useful and *portable*
programme, and meet the requirements of the IOCCC. I initially
planned to have a mini CURSES built-in like the IOCCC Tetris entry
from a previous year, however this was not as portable as using a
CURSES library with TERMINFO/TERMCAP support.
REFERENCES
[Fin80] Craig A. Finseth, "Theory and Practice of Text Editors or
A Cookbook For An EMACS", TM-165, MIT Lab. for Computer
Science
[KeP81] Kernighan & Plauger, "Software Tools in Pascal",
Addison-Wesley, 81, chapter 6
[Mil86] Eugene W. Myers & Webb Miller, "Row-replacement Algorithums
for Screen Editors", TR 86-19, Dept. of Compter Science,
U. of Arizona
[MyM86] Eugene W. Myers & Webb Miller, "A simple row-replacement
method", TR 86-28, Dept. of Compter Science, U. of Arizona
[Mil87] Webb Miller, "A Software Tools Sampler", Prentice Hall, 87
ISBN 0-13-822305-X, chapter 5
[net90] "Editor 101/102" articles from comp.editors
FILES
ae.c Obfuscated source
ae.man Manual page
---how to ANSI compile---
---how to common compile---
X # SYS V
X cc -DMODE=0600 -DBUF=32767 -o ae ae.c -lcurses
X # BSD
X #cc -DMODE=0600 -DBUF=32767 -o ae ae.c -lcurses -ltermcap
X # ATARI ST
X #cc -DMODE=0 -DBUF=32767 -o ae.ttp ae.c curses.a
X # PC class
X #wcl -mc -DMODE=0 -DBUF=32767 ae.c curses.lib
---program---
X#include <curses.h>
X#define Z(x) (x==' '||x=='\t'||x=='\n')
Xint a,d,i,q=1,x,y;char b[BUF],*c,*g=b,*h,*p=b,*m=b,*n,*f,
Xk[]="hjklHJKL[]tbixWRQ";S(){p=b;}T(){p=c;}Q(){q=0;}P(){clear();Y();}
XV(){if(p<g)while(p<g)*--h= *--g;if(h<=p)while(h<p)*g++= *h++;p=h;}
Xchar*M(s)char*s;{while(b<(s=s-h?s:g)&&*--s!='\n');return b<s?s+1:b;}
Xchar*N(s)char*s;{while((s=s-g?s:h)<c&&*s++!='\n');return s<c?s:c;}
XA(){for(i=0,p=p-g?p:h;p<c&&*p!='\n'&&i<x;i+= *p-'\t'?1:8-(i&7),R());}
XL(){p=h-p?p:g;b<p&&--p;--y;}R(){p=p-g?p:h;p<c&&++p;}U(){p=M(M(p)-1);A();--y;}
XD(){p=N(p);A();}H(){p=M(p);}E(){p=N(p);L();}
XB(){while(!Z(*p)&&b<p)L();while(Z(*p)&&b<p)L();}
XJ(){m=p=M(M(n)-1);while(y--)p=N(p);A();n=c;}
XK(){for(i=d;--i;m=M(M(m)-1),p=M(M(p)-1));A();}
XW(){while(!Z(*p)&&p<c)R();while(Z(*p)&&p<c)R();}
XI(){V();while((a=getch())-'\f'){if(a-'\b')h-g&&(*g++=a-'\r'?a:'\n');
Xelse b<g&&--g;Y();}}X(){V();p=h<c?++h:p;}
XF(){p=b;V();write(i=creat(f,MODE),h,(int)(c-h));close(i);}
X(*z[])()={L,D,U,R,B,J,K,W,H,E,S,T,I,X,F,P,Q,V};
XY(){if(p<m)m=M(p);if(n<=p||++y==d)for(m=N(p),i=m-c?d:d-2;i--;m=M(M(m)-1));
Xmove(0,0);for(i=a=0,n=m;;){n=n-g?n:h;n-p||(y=i,x=a);if(d<=i||c<=n)break;
X*n-'\r'&&(addch(*n),a+= *n-'\t'?1:8-(a&7));if(*n++=='\n'||COLS<=a)++i,a=0;}
Xclrtobot();++i<d&&mvaddstr(i,0,"<< EOF >>");move(y,x);refresh();}
Xmain(u,v)char**v;{h=n=c=b+BUF;if(u<2)return 2;initscr();d=LINES;raw();
Xnoecho();idlok(stdscr,1);
Xif(0<(i=open(f= *++v,0)))g+=read(i,b,BUF),g=g<b?b:g,close(i);while(q){Y();
Xfor(a=getch(),i=0;k[i]&&a!=k[i];++i);(*z[i])();}endwin();return 0;}
---end---
--
ant@mks.com Anthony C Howe
Mortice Kern Systems Inc. 35 King St. N., Waterloo, Ontario, Canada, N2J 6W9
"Fate favors fools, small children, and ships named Enterprise" - Riker
Technical Details
Message-ID:
<1991May30.130945.4341@mks.com>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!zaphod.mps.ohio-state.edu!caen!news.cs.indiana.edu!maytag!mks.com!antShow Full Headers
Complete Article Headers
Newsgroups: comp.editors Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!zaphod.mps.ohio-state.edu!caen!news.cs.indiana.edu!maytag!mks.com!ant From: ant@mks.com (Anthony Howe) Subject: Simple Editor (IOCCC '91 Entry) Date: Thu, 30 May 91 13:09:45 GMT Message-ID: <1991May30.130945.4341@mks.com> Organization: Mortice Kern Systems, Waterloo, Ontario, CANADA Sender: ant@mks.com (Anthony Howe)