minix/commands/elle/eeedit.c
2009-11-09 10:26:00 +00:00

718 lines
15 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
* This software is quasi-public; it may be used freely with
* like software, but may NOT be sold or made part of licensed
* products without permission of the author.
*/
/* EEEDIT - E-type routines */
#include "elle.h"
/* E_ - Operate on cur_buf. Do not change value of cur_dot unless
* unavoidable side effect (also e_setcur).
* EX_ - Like E_ but take SB ptr value. Never touch cur_dot.
* ED_ - Like E_, operate on cur_buf, update cur_dot and display stuff.
* D_ - Perform necessary display update for given operations.
*
* Note that "dot" refers to the current read/write pointer for a sbbuffer.
* The name comes from EMACS/TECO where "." represents this value.
*/
#define CURSBB (SBBUF *)cur_buf /* Shorthand for current SB buffer */
e_reset() /* Reset current buffer */
{ ex_reset(CURSBB);
cur_dot = 0;
}
/* Basic functions - apply SB routines to current buffer.
* There is some optimization here which knows that certain SB functions
* are macros.
*/
e_rgetc() /* Read/move 1 char backward */
{ return(sb_rgetc((CURSBB)));
}
e_rdelc() /* Delete 1 char backward */
{ return(sb_rdelc((CURSBB)));
}
e_delc() /* Delete 1 char forward */
{ return(sb_deln(CURSBB,(chroff)1));
}
e_getc() /* Read/move 1 char forward */
{ register SBBUF *sb;
sb = CURSBB; /* Macro: use reg */
return(sb_getc(sb));
}
e_backc() /* Move 1 char backward */
{ register SBBUF *sb;
sb = CURSBB; /* Macro: use reg */
sb_backc(sb); /* No value returned */
}
e_putc(c) /* Insert/write 1 char forward */
char c;
{ register SBBUF *sb;
sb = CURSBB; /* Macro: use reg */
return(sb_putc(sb, c));
}
e_peekc() /* Read 1 char forward (no move) */
{ register SBBUF *sb;
sb = CURSBB; /* Macro: use reg */
return(sb_peekc(sb));
}
e_ovwc(ch) /* Overwrite 1 char forward */
char ch;
{
sb_setovw(CURSBB); /* Turn on overwrite mode */
e_putc(ch);
sb_clrovw(CURSBB); /* Turn off overwrite mode */
}
SBSTR *
e_copyn(off) /* Copy N chars forward/backward, return SD to sbstring */
chroff off;
{ return(sb_cpyn(CURSBB,off));
}
e_deln(off) /* Delete N chars forward/backward */
chroff off;
{ return(sb_deln(CURSBB, off));
}
/* E_SETCUR() - set cur_dot to current position (dot). This is the only
* E_ routine that mungs cur_dot except for e_reset.
*/
e_setcur()
{ cur_dot = e_dot();
}
e_gosetcur(dot) /* Go to specified dot and set cur_dot as well */
chroff dot;
{ sb_seek(CURSBB,dot,0);
e_setcur(); /* Not cur_dot = dot since want canonicalization */
}
/* E_GO(dot) - Move to specified location. */
/* These "GO" routines all move to the location specified, returning
* 0 if successful and -1 on error. "cur_dot" is never changed,
* with the exception of e_gosetcur.
* Note that other "GO" routines (eg E_GONL) will return 1 if successful
* and 0 if stopped by EOF.
*/
e_gocur() { return(e_go(cur_dot)); } /* Move to cur_dot */
e_gobob() { return(e_go((chroff) 0)); } /* Move to Beg Of Buffer */
e_goeob() { return(sb_seek(CURSBB,(chroff)0,2)); } /* Move to End Of Buffer */
e_go(dot) /* Move to specified location. */
chroff dot;
{ return(sb_seek(CURSBB,dot,0));
}
e_igoff(ioff) /* Move (int) N chars forward/backward */
int ioff;
{ return(sb_seek(CURSBB,(chroff)ioff,1));
}
e_goff(off) /* Move (full) N chars forward/backward */
chroff off;
{ return(sb_seek(CURSBB,off,1));
}
int ex_gonl(), ex_gopl(), ex_gobol(), ex_goeol();
e_gobol() { return(ex_gobol(CURSBB)); } /* Move to beg of this line */
e_goeol() { return(ex_goeol(CURSBB)); } /* Move to end of this line */
e_gonl() { return(ex_gonl(CURSBB)); } /* Move to beg of next line */
e_gopl() { return(ex_gopl(CURSBB)); } /* Move to beg of prev line */
/* E_DOT() - Return current value of dot. */
chroff e_dot() { return(sb_tell(CURSBB)); } /* Current pos */
chroff e_nldot() { return(e_alldot(CURSBB,ex_gonl)); } /* Beg of next line */
chroff e_pldot() { return(e_alldot(CURSBB,ex_gopl)); } /* Beg of prev line */
chroff e_boldot(){ return(e_alldot(CURSBB,ex_gobol));} /* Beg of this line */
chroff e_eoldot(){ return(e_alldot(CURSBB,ex_goeol));} /* End of this line */
chroff
e_alldot(sbp,rtn) /* Auxiliary for above stuff */
SBBUF *sbp;
int (*rtn)();
{ return(ex_alldot(sbp,rtn,e_dot()));
}
/* E_BLEN - Return length of current buffer */
chroff
e_blen() { return(ex_blen(CURSBB)); }
/* EX_ routines - similar to E_ but take a buffer/sbbuf argument
* instead of assuming current buffer.
*/
/* EX_RESET - Reset a given buffer */
ex_reset(b)
struct buffer *b;
{ sbs_del(sb_close((SBBUF *)b));
sb_open((SBBUF *)b,(SBSTR *)0);
}
ex_go(sbp,loc) /* Move to given dot in specified sbbuf */
chroff loc;
SBBUF *sbp;
{ return(sb_seek(sbp,loc,0));
}
chroff
ex_dot(sbp) /* Return current position in specified sbbuf */
SBBUF *sbp;
{
return(sb_tell(sbp));
}
chroff
ex_boldot(sbp,dot) /* Return dot for BOL of specified sbbuf */
SBBUF *sbp;
chroff dot;
{ return(ex_alldot(sbp,ex_gobol,dot));
}
chroff
ex_alldot(sbp,rtn,dot) /* Auxiliary for some e_ stuff */
SBBUF *sbp;
int (*rtn)();
chroff dot;
{ register SBBUF *sb;
chroff savloc, retloc;
savloc = sb_tell(sb = sbp);
sb_seek(sb,dot,0);
(*rtn)(sb);
retloc = sb_tell(sb);
sb_seek(sb,savloc,0);
return(retloc);
}
/* GO (forward) to Next Line of specified sbbuf - returns 0 if stopped at EOF
* before an EOL is seen. */
ex_gonl(sbp)
SBBUF *sbp;
{ register SBBUF *sb;
register int c;
sb = sbp;
#if FX_EOLMODE
if(eolcrlf(sb))
while((c = sb_getc(sb)) != EOF)
{ if(c == LF) /* Possible EOL? */
{ sb_backc(sb); /* See if prev char was CR */
if((c = sb_rgetc(sb)) != EOF)
sb_getc(sb);
sb_getc(sb); /* Must restore position */
if(c == CR) /* Now test for CR */
return(1); /* Won, CR-LF! */
}
}
else
#endif
while((c = sb_getc(sb)) != EOF)
if(c == LF)
return(1);
return(0);
}
/* GO (forward) to End Of Line of specified sbbuf - returns 0 if stopped at
* EOF before an EOL is seen. */
ex_goeol(sbp)
SBBUF *sbp;
{ register SBBUF *sb;
register int c;
sb = sbp;
#if FX_EOLMODE
if(eolcrlf(sb))
while((c = sb_getc(sb)) != EOF)
{ if(c == LF) /* Possible EOL? */
{ sb_backc(sb); /* See if prev char was CR */
if((c = sb_rgetc(sb)) == CR)
return(1); /* Won, CR-LF! */
if(c != EOF) /* No, must restore position */
sb_getc(sb); /* Skip over */
sb_getc(sb); /* Skip over LF */
}
}
else
#endif
while((c = sb_getc(sb)) != EOF)
if(c == LF)
{ sb_backc(sb);
return(1);
}
return(0);
}
/* GO (backward) to Beg Of Line of specified sbbuf - returns 0 if stopped
* at EOF
*/
ex_gobol(sbp)
SBBUF *sbp;
{ register SBBUF *sb;
register int c;
sb = sbp;
#if FX_EOLMODE
if(eolcrlf(sb))
while((c = sb_rgetc(sb)) != EOF)
{ if(c == LF) /* Possible EOL? */
{ if((c = sb_rgetc(sb)) == CR)
{ sb_getc(sb); /* Won, CR-LF! */
sb_getc(sb); /* Move back */
return(1);
}
if(c != EOF) /* No, must restore position */
sb_getc(sb); /* Undo the rgetc */
}
}
else
#endif
while((c = sb_rgetc(sb)) != EOF)
if(c == LF)
{ sb_getc(sb);
return(1);
}
return(0);
}
/* GO (backward) to Previous Line of specified sbbuf - returns 0 if stopped
* at EOF before an EOL is seen (i.e. if already on 1st line of buffer)
*/
ex_gopl(sbp)
SBBUF *sbp;
{ register SBBUF *sb;
register int c;
sb = sbp;
#if FX_EOLMODE
if(eolcrlf(sb))
while((c = sb_rgetc(sb)) != EOF)
{ if(c == LF) /* Possible EOL? */
{ if((c = sb_rgetc(sb)) == CR)
{ ex_gobol(sb);
return(1); /* Won! */
}
if(c != EOF) /* No, must restore position */
sb_getc(sb); /* Undo the rgetc */
}
}
else
#endif
while((c = sb_rgetc(sb)) != EOF)
if(c == LF)
{ ex_gobol(sb);
return(1); /* Won! */
}
return(0);
}
chroff
ex_blen(sbp) /* Return length of specified sbbuf */
SBBUF *sbp;
{
return(sb_tell(sbp)+sb_ztell(sbp));
}
/* Miscellaneous stuff */
/* E_GOFWSP() - Forward over whitespace */
e_gofwsp()
{ register int c;
while((c = e_getc()) == SP || c == TAB);
if(c != EOF) e_backc();
}
/* E_GOBWSP() - Backward over whitespace */
e_gobwsp()
{ register int c;
while((c = e_rgetc()) == SP || c == TAB);
if(c != EOF) e_getc();
}
/* E_GOLINE(n) - Goes N lines forward (or backward).
** If N == 0, goes to beginning of current line.
** Returns 0 if hit EOF.
*/
e_goline(i)
register int i;
{
if(i > 0)
{ do { if(!e_gonl()) return(0); }
while(--i);
}
else if(i < 0)
{ i = -i;
do { if(!e_gopl()) return(0); }
while(--i);
}
else e_gobol(); /* arg of 0 */
return 1;
}
/* E_LBLANKP() - Returns true if all characters in rest of line are blank.
* Moves to beginning of next line as side effect, unless fails.
*/
e_lblankp()
{ register int c;
for(;;) switch(e_getc())
{
case SP:
case TAB:
continue;
case LF: /* Normally drop thru to return 1 as for EOF */
#if FX_EOLMODE
if(eolcrlf(cur_buf))
{ e_rgetc();
if((c = e_rgetc()) != EOF) /* Get prev char */
e_getc();
e_getc();
if(c != CR) /* Now examine */
continue; /* Not CR-LF, go on */
} /* Else drop thru to return win */
#endif
case EOF:
return(1);
default:
return(0);
}
/* Never drops out */
}
e_insn(ch, cnt)
int ch;
int cnt;
{ register int i;
if((i = cnt) > 0)
do { e_putc(ch);
} while(--i);
}
e_sputz(acp)
char *acp;
{ register SBBUF *sb;
register char *cp;
register int c;
if(cp = acp)
{ sb = CURSBB;
while(c = *cp++)
sb_putc(sb,c);
}
}
/* BOLEQ - Returns TRUE if 2 dots are on the same line
* (i.e. have the same Beg-Of-Line)
*/
boleq(dot1,dot2)
chroff dot1,dot2;
{ return( (ex_boldot(CURSBB,dot1) == ex_boldot(CURSBB,dot2)));
}
char *
dottoa(str,val)
char *str;
chroff val;
{ register char *s;
s = str;
if(val < 0)
{ *s++ = '-';
val = -val;
}
if(val >= 10)
s = dottoa(s, val/10);
*s++ = '0' + (int)(val%10);
*s = 0;
return(s);
}
/* Paragraph utilities */
#if FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA
#if FX_SFPREF
extern char *fill_prefix; /* Defined in eefill.c for now */
extern int fill_plen; /* Ditto */
#endif /*FX_SFPREF*/
#if ICONOGRAPHICS
int para_mode = PARABLOCK; /* eexcmd.c only other file that refs this */
#endif /*ICONOGRAPHICS*/
/* Go to beginning of paragraph */
e_gobpa()
{ register int c;
chroff savdot;
savdot = e_dot();
e_bwsp();
while((c = e_rgetc()) != EOF)
if(c == LF) /* Went past line? */
{ e_getc(); /* Back up and check */
#if FX_SFPREF
if(fill_plen)
if(tstfillp(fill_plen))
{ e_igoff(-(fill_plen+1));
continue;
}
else break;
#endif /*FX_SFPREF*/
#if ICONOGRAPHICS
c = e_peekc ();
if (para_mode == PARABLOCK)
if (c == LF)
break;
if (para_mode == PARALINE)
if (c_wsp (c))
break;
#else
if(c_pwsp(e_peekc())) /* Check 1st chr for wsp */
break; /* If wsp, done */
#endif /*ICONOGRAPHICS*/
e_rgetc(); /* Nope, continue */
}
if((c = e_peekc()) == '.' || c == '-')
{ e_gonl();
if(e_dot() >= savdot)
e_gopl();
}
}
/* Go to end of paragraph */
e_goepa()
{ register int c;
e_gobol(); /* First go to beg of cur line */
e_fwsp();
while((c = e_getc()) != EOF)
if (c == LF)
{
#if FX_SFPREF
if(fill_plen) /* If Fill Prefix is defined */
if(tstfillp(fill_plen)) /* then must start with it */
continue;
else break; /* or else we're done */
#endif /*FX_SFPREF*/
#if ICONOGRAPHICS
if (para_mode == PARABLOCK)
if (e_peekc () == LF)
break;
if (para_mode == PARALINE)
if (c_wsp (e_peekc ()))
break;
#else
if(c_pwsp(e_peekc()))
break;
#endif /*-ICONOGRAPHICS*/
}
}
exp_do(rpos, rneg)
int (*rpos)(), (*rneg)();
{ register int e;
register int (*rtn)();
if((e = exp) == 0)
return;
rtn = rpos;
if(e < 0)
{ rtn = rneg;
e = -e;
}
do { (*rtn)();
} while(--e);
}
e_fwsp()
{ register int c;
while(c_wsp(c = e_getc()));
if(c != EOF) e_backc();
}
e_bwsp()
{ register int c;
while(c_wsp(c = e_rgetc()));
if(c != EOF) e_getc();
}
c_wsp(ch)
int ch;
{ register int c;
c = ch;
if(c == SP || c == TAB || c == LF || c == FF)
return(1);
return(0);
}
c_pwsp(ch)
int ch;
{ register int c;
c = ch;
if(c == '.' || c == '-')
return(1);
return(c_wsp(c));
}
#endif /* FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA */
/* Word function auxiliaries */
/* Returns true if this character is a delimiter. */
delimp(c)
int c;
{ static int delim_tab[] =
{
0177777, 0177777, /* All controls */
0177777, 0176000, /* All punct but 0-9 */
0000001, 0074000, /* All punct but A-Z and _ */
0000001, 0174000 /* All punct but a-z */
};
return (delim_tab[c >> 4] & (1 << (c & 017)));
}
e_wding(adot,n)
register chroff *adot;
int n;
{ chroff savdot;
savdot = e_dot();
e_gowd(n);
*adot = e_dot();
e_go(savdot);
if(*adot == savdot)
{ ring_bell();
return(0);
}
return(1);
}
chroff
e_wdot(dot,n)
chroff dot;
int n;
{ chroff savdot, retdot;
savdot = e_dot();
e_go(dot);
e_gowd(n);
retdot = e_dot();
e_go(savdot);
return(retdot);
}
e_gowd(n)
int n;
{ register int (*gch)(), c, cnt;
int e_getc(), e_rgetc();
chroff ret_dot;
if((cnt = n) == 0)
return;
if(cnt > 0)
gch = e_getc; /* Forward routine */
else
{ gch = e_rgetc; /* Backward routine */
cnt = -cnt;
}
do
{ ret_dot = e_dot(); /* Remember dot for last word found */
while((c = (*gch)()) != EOF && delimp(c));
if(c == EOF)
{ e_go(ret_dot); /* Use last word found */
break;
}
while((c = (*gch)()) != EOF && !delimp(c));
if(c == EOF)
break;
if(n < 0) e_getc(); else e_backc();
} while(--cnt);
}
/* Searching */
e_search(mstr,mlen,backwards)
char *mstr;
int mlen;
int backwards;
{ register SBBUF *sb;
register char *cp;
register int c;
char *savcp;
int cnt, scnt;
#if IMAGEN
register int c1;
register int caseless = (cur_buf->b_flags & B_TEXTMODE);
#endif /*IMAGEN*/
sb = (SBBUF *) cur_buf;
if (!backwards)
{ /* Search forwards */
sfwd: cp = mstr;
while((c = sb_getc(sb)) != EOF)
{
#if IMAGEN
if((!caseless && c != *cp) ||
(caseless && upcase(c) != upcase(*cp))) continue;
#else
if(c != *cp) continue;
#endif /*-IMAGEN*/
cp++;
cnt = mlen;
while(--cnt > 0)
{
#if IMAGEN
c1 = *cp++;
c = e_getc();
if ((!caseless && c1 != c) ||
(caseless && upcase(c1) != upcase(c)))
#else
if(*cp++ != (c = e_getc()))
#endif /*-IMAGEN*/
{ if(c == EOF) return(0);
sb_seek(sb,(chroff)(cnt-mlen),1);
goto sfwd;
}
}
return(1);
}
}
else
{ /* Search backwards */
scnt = mlen - 1;
savcp = mstr + scnt; /* Point to end of string */
sbck: cp = savcp;
while((c = sb_rgetc(sb)) != EOF)
{
#if IMAGEN
if((!caseless && c != *cp) ||
(caseless && upcase(c) != upcase(*cp))) continue;
#else
if(c != *cp) continue;
#endif /*-IMAGEN*/
cp--;
if((cnt = scnt) == 0) return(1);
do
{
#if IMAGEN
c1 = *cp--;
c = e_rgetc();
if ((!caseless && c1 != c) ||
(caseless && upcase(c1) != upcase(c)))
#else
if(*cp-- != (c = e_rgetc()))
#endif /*-IMAGEN*/
{ if(c == EOF) return(0);
sb_seek(sb,(chroff)(mlen-cnt),1);
goto sbck;
}
}
while(--cnt);
return(1);
}
}
return(0); /* Failed */
}