#include "stdio.h"
#include "ed.h"
/* ovudfb31.c: (read "up down forward back" for "udfb")
** overlay 31 source code.
** this large overlay is a portmanteau of frequently-used
** commands. One can hardly justify having some of them in
** overlays UNLESS the overlay in question is one which is
** likely to be in memory at all times -- so, this overlay
** includes gobs of the most useful commands.
*/
extern int wstyle; /* Which kind of Word operations? */
extern int currow; /* set by update() */
extern int tabsize; /* if tabs are expanded to spaces. */
extern char *kbufp; /* Kill buffer data */
extern int kused; /* # of bytes used in KB */
extern int ksize; /* # of bytes allocated in KB */
#define TABCASE 40 /* case TABCASE and above are special. */
/* cases < TABCASE are numbered so that we can handle a negative
** parameter with "casenumber ^= 1"
*/
ovmain( x )
#define cmdflag (*(int *)0x102)
#define cmdparm (*(int *)0x104)
{
register LINE * mylp;
register WINDOW * mywp;
#define temp_int (*(int *)0xc0)
#define mydoto (*(int *)0xc2)
#define xbufchar (*(int *)0xc4)
#define limitp (*(LINE **)0xc6)
#define localx (*(int *)0xc8)
#define xinsct (*(int *)0xca)
#define mylen (*(int *)0xcc)
#define Wdoto (*(int *)0xce)
/* the above #defines are temporary variables, in effect:
** the compiler generates much smaller code for specific addresses
** than it does for stack variables.
*/
xinsct = 1;
mywp = curwp;
mylp = mywp->w_dotp;
limitp = curbp->b_linep;
temp_int = mydoto = 0;
mylen = llength( mylp );
Wdoto = mywp->w_doto;
if ( ( localx = x ) < TABCASE )
{ /* most commands here have negative-parameter counterparts. */
if ( cmdparm < 0 )
{ localx ^= 1;
cmdparm = -cmdparm;
}
}
switch ( localx )
{
case 13: /* goto end of line. */
mydoto = mylen;
goto dotpset;
case 12: /* goto start of line. */
if ( cmdflag && ( mydoto = cmdparm -1 ) > mylen )
mydoto = mylen;
goto dotpset;
case 10: /* page forwards */
case 11: /* page back. */
cmdparm *= ( mywp->w_ntrows - 1 );
goto linemotion;
case 1: /* up arrow. */
++cmdparm;
goto linemo2; /* backward goes n+1 lines! */
case 9: /* gotoeob */
if ( cmdparm ) --cmdparm;
case 8: /* gotobob */
mylp = curbp->b_linep;
linemotion:
/* if ( localx & 1 ) */
/* { mylp = lforw( mylp ); */
/* } */
curgoal = curcol = 0;
/* mywp->w_flag |= WFHARD; */
linemo2: /* fall through. */
case 0: /* down arrow */
{ /* up or down */
if ( ! ( lastflag & CFCPCN ))
{ /* Reset goal if last not up/down */
curgoal = curcol;
}
thisflag |= CFCPCN;
if ( localx & 1 ) /* backward */
{ while ( decparm()
&& ( mylp = lback( mylp )) != limitp
);
}
else
{ while ( decparm()
&& ( mylp = lforw( mylp )) != limitp
);
} /* "--n >= 0" for n+1 lines. */
while ( mydoto != llength( mylp ))/* NOT mylen! */
{ if ( ( xbufchar = lgetc( mylp, mydoto ))
== '\t' )
temp_int |= 0x07;
else if ( ! isinsert( xbufchar ))
plustemp();
if ( ++temp_int > curgoal ) break;
++mydoto;
}
dotpmove: wfmove();
dotpset: mywp->w_dotp = mylp;
mywp->w_doto = mydoto;
goto rettrue; /* return ( 1 ); */
} /* end case 0 or 1 */
case 2: /* word forward */
case 4: /* del word forward */
{ /* mylp = curwp->w_dotp; at top (mylp) */
mydoto = Wdoto;
while ( decparm())
{ if ( ! ( wstyle & 2 ) && ! fwx())
{ goto retfalse;
}
while ( inword( ))
{ fc1();
/* assert the above cannot fail. */
plustemp();
}
if ( wstyle & 2 && ! fwx())
{ goto retfalse;
}
}
if ( localx == 2 ) goto rettrue;
mywp->w_dotp = mylp;
mywp->w_doto = mydoto;
goto retldel; /* return ( ldelete( temp_int, 1 )); */
} /* end case 2 or 4 */
case 3: /* word backward */
case 5: /* del word backward */
{
if ( ! bc1( )) goto retfalse; /* TOF */
/* temp_int++; */
while ( decparm())
{
while ( ! inword( ))
{ if ( ! bc1()) goto retfalse;
plustemp();
}
while ( inword( ))
{ if ( ! bc1())
{ /* top of file. */
retfalse: return ( 0 );
}
plustemp();
}
}
/* temp_int--; */
fc1(); /* can't fail. */
if ( localx == 5 )
{ /* delword. */
retldel: cmdflag = 1;
ret2ldel: return ( ldelete( temp_int, cmdflag ));
}
rettrue: return ( 1 );
} /* end case 3 or 5. */
case 6: /* forwdel() */
case 7: /* backdel() */
{
if ( cmdflag )
{ /* Really a kill. */
kdcheck();
}
if ( ( localx & 1 ) && ! backchar( cmdflag, cmdparm ))
goto retfalse;
temp_int = cmdparm;
goto ret2ldel; /*return(ldelete(cmdparm,cmdflag));*/
} /* end cases 6 and 7 */
case TABCASE:
{ /* with no parameter, perform tab function;
** with one, set tabsize.
*/
if ( cmdparm < 0 ) return ( 0 );
if ( cmdparm != 1 )
{ tabsize = cmdparm;
return( 1 );
}
xbufchar = '\t';
if ( tabsize )
{ xinsct = tabsize -
( ( curcol + 1 ) % tabsize );
xbufchar = ' ';
}
return( xlinsc( ));
} /* end case TABCASE */
case TABCASE+1: /* openline() */
case TABCASE+2: /* indent() */
{ /* openline() keeps cursor in same place,
** inserts arg newlines.
** indent() moves forward with its newlines,
** adds whitespace to match the current line.
*/
mylp = lback( mylp );
mydoto = Wdoto;
while ( decparm()) if ( ! lnewline()) goto retfalse;
mylp = lforw( mylp );
/* lnewline() may delete the original
** target of mylp.
*/
if ( localx == ( TABCASE + 1 ))
{ /* openline(), done. */
goto dotpset;
}
while ( ( xbufchar = lgetc( mylp, ++cmdparm )) == ' '
|| xbufchar == '\t' )
{ xlinsc( );
}
if ( xbufchar == '{' )
{ /* C indent */
xbufchar = '\t';
xlinsc();
}
goto rettrue;
} /* end case indent() and openline() */
case TABCASE+7: /* vi-style kill. */
cmdflag = 1;
mywp->w_doto = Wdoto = 0; /* fall through. */
case TABCASE+3: /* kill() */
{ kdcheck();
mydoto = Wdoto;
if ( ! cmdflag )
{ temp_int = mylen - mydoto;
if ( temp_int == 0 ) temp_int = 1;
} else if ( ! cmdparm )
{ temp_int = mydoto;
mywp->w_doto = 0;
} else if ( decparm()) /* "if n > 0" */
{ temp_int = mylen - mydoto + 1;
mylp = lforw( mylp );
while (decparm()) /* while --n */
{ if ( mylp == limitp )
goto retfalse;
temp_int += llength( mylp ) + 1;
mylp = lforw( mylp );
}
} else
{ /* mlwrite("neg kill"); */
ctrlg();
goto retfalse;
}
goto retldel; /*return(ldelete(temp_int,TRUE));*/
} /* end case "kill()" */
case TABCASE+4: /* yank() */
{ if ( ! decparm()) goto retfalse;
do /* make cmdparm copies. */
{ temp_int = 0;
while ( temp_int < kused )
{ if ( ( xbufchar = kbufp[ temp_int ])
== '\n' )
{ lnewline( );
} else
{ if ( ! xlinsc())
goto retfalse;
}
plustemp();
}
} while ( decparm( ));
goto rettrue;
} /* end case yank() */
case TABCASE+5: /* set mark */
{ mlwrite("[Mark]");
markset: mywp->w_markp = mylp;
mywp->w_marko = Wdoto;
goto rettrue;
} /* end case set mark */
case TABCASE+6: /* exchange mark and cursor. */
{ if ( mywp->w_markp == NULL )
{ mlwrite("No mark");
return ( 0 );
}
mywp->w_dotp = mywp->w_markp;
mywp->w_doto = mywp->w_marko;
wfmove();
goto markset;
} /* end case ^X^X */
}
}
fc1() /* saves 10 bytes per call to it. */
{ return( forwchar( 0, 1 ));
}
bc1() /* saves 10 bytes per call to it. */
{ return( backchar( 0, 1 ));
}
fwx() /* loop used twice in forwword. */
{ while ( ! inword( ))
{ if ( ! fc1( )) return ( 0 );
plustemp();
}
return ( 1 );
}
plustemp() /* temp_int++ : saves 2 bytes per call. */
{ ++temp_int;
}
decparm() /* --cmdparm >= 0 */
{ return ( --cmdparm >= 0 );
}
xlinsc()
{ return( linsert( xinsct, xbufchar ));
}
kdcheck()
{ if ( ! ( lastflag & CFKILL )) kdelete();
thisflag |= CFKILL;
}
wfmove()
{ curwp->w_flag |= WFMOVE;
}