1 /* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
2 * This software is quasi-public; it may be used freely with
3 * like software, but may NOT be sold or made part of licensed
4 * products without permission of the author.
6 /* EEEDIT - E-type routines */
10 /* E_ - Operate on cur_buf. Do not change value of cur_dot unless
11 * unavoidable side effect (also e_setcur).
12 * EX_ - Like E_ but take SB ptr value. Never touch cur_dot.
13 * ED_ - Like E_, operate on cur_buf, update cur_dot and display stuff.
14 * D_ - Perform necessary display update for given operations.
16 * Note that "dot" refers to the current read/write pointer for a sbbuffer.
17 * The name comes from EMACS/TECO where "." represents this value.
20 #define CURSBB (SBBUF *)cur_buf /* Shorthand for current SB buffer */
22 e_reset() /* Reset current buffer */
27 /* Basic functions - apply SB routines to current buffer.
28 * There is some optimization here which knows that certain SB functions
31 e_rgetc() /* Read/move 1 char backward */
32 { return(sb_rgetc((CURSBB
)));
34 e_rdelc() /* Delete 1 char backward */
35 { return(sb_rdelc((CURSBB
)));
37 e_delc() /* Delete 1 char forward */
38 { return(sb_deln(CURSBB
,(chroff
)1));
40 e_getc() /* Read/move 1 char forward */
42 sb
= CURSBB
; /* Macro: use reg */
45 e_backc() /* Move 1 char backward */
47 sb
= CURSBB
; /* Macro: use reg */
48 sb_backc(sb
); /* No value returned */
50 e_putc(c
) /* Insert/write 1 char forward */
53 sb
= CURSBB
; /* Macro: use reg */
54 return(sb_putc(sb
, c
));
56 e_peekc() /* Read 1 char forward (no move) */
58 sb
= CURSBB
; /* Macro: use reg */
61 e_ovwc(ch
) /* Overwrite 1 char forward */
64 sb_setovw(CURSBB
); /* Turn on overwrite mode */
66 sb_clrovw(CURSBB
); /* Turn off overwrite mode */
70 e_copyn(off
) /* Copy N chars forward/backward, return SD to sbstring */
72 { return(sb_cpyn(CURSBB
,off
));
74 e_deln(off
) /* Delete N chars forward/backward */
76 { return(sb_deln(CURSBB
, off
));
79 /* E_SETCUR() - set cur_dot to current position (dot). This is the only
80 * E_ routine that mungs cur_dot except for e_reset.
85 e_gosetcur(dot
) /* Go to specified dot and set cur_dot as well */
87 { sb_seek(CURSBB
,dot
,0);
88 e_setcur(); /* Not cur_dot = dot since want canonicalization */
91 /* E_GO(dot) - Move to specified location. */
92 /* These "GO" routines all move to the location specified, returning
93 * 0 if successful and -1 on error. "cur_dot" is never changed,
94 * with the exception of e_gosetcur.
95 * Note that other "GO" routines (eg E_GONL) will return 1 if successful
96 * and 0 if stopped by EOF.
99 e_gocur() { return(e_go(cur_dot
)); } /* Move to cur_dot */
100 e_gobob() { return(e_go((chroff
) 0)); } /* Move to Beg Of Buffer */
101 e_goeob() { return(sb_seek(CURSBB
,(chroff
)0,2)); } /* Move to End Of Buffer */
102 e_go(dot
) /* Move to specified location. */
104 { return(sb_seek(CURSBB
,dot
,0));
106 e_igoff(ioff
) /* Move (int) N chars forward/backward */
108 { return(sb_seek(CURSBB
,(chroff
)ioff
,1));
111 e_goff(off
) /* Move (full) N chars forward/backward */
113 { return(sb_seek(CURSBB
,off
,1));
116 int ex_gonl(), ex_gopl(), ex_gobol(), ex_goeol();
118 e_gobol() { return(ex_gobol(CURSBB
)); } /* Move to beg of this line */
119 e_goeol() { return(ex_goeol(CURSBB
)); } /* Move to end of this line */
120 e_gonl() { return(ex_gonl(CURSBB
)); } /* Move to beg of next line */
121 e_gopl() { return(ex_gopl(CURSBB
)); } /* Move to beg of prev line */
124 /* E_DOT() - Return current value of dot. */
125 chroff
e_dot() { return(sb_tell(CURSBB
)); } /* Current pos */
126 chroff
e_nldot() { return(e_alldot(CURSBB
,ex_gonl
)); } /* Beg of next line */
127 chroff
e_pldot() { return(e_alldot(CURSBB
,ex_gopl
)); } /* Beg of prev line */
128 chroff
e_boldot(){ return(e_alldot(CURSBB
,ex_gobol
));} /* Beg of this line */
129 chroff
e_eoldot(){ return(e_alldot(CURSBB
,ex_goeol
));} /* End of this line */
132 e_alldot(sbp
,rtn
) /* Auxiliary for above stuff */
135 { return(ex_alldot(sbp
,rtn
,e_dot()));
138 /* E_BLEN - Return length of current buffer */
140 e_blen() { return(ex_blen(CURSBB
)); }
142 /* EX_ routines - similar to E_ but take a buffer/sbbuf argument
143 * instead of assuming current buffer.
146 /* EX_RESET - Reset a given buffer */
149 { sbs_del(sb_close((SBBUF
*)b
));
150 sb_open((SBBUF
*)b
,(SBSTR
*)0);
153 ex_go(sbp
,loc
) /* Move to given dot in specified sbbuf */
156 { return(sb_seek(sbp
,loc
,0));
160 ex_dot(sbp
) /* Return current position in specified sbbuf */
163 return(sb_tell(sbp
));
168 ex_boldot(sbp
,dot
) /* Return dot for BOL of specified sbbuf */
171 { return(ex_alldot(sbp
,ex_gobol
,dot
));
175 ex_alldot(sbp
,rtn
,dot
) /* Auxiliary for some e_ stuff */
179 { register SBBUF
*sb
;
180 chroff savloc
, retloc
;
182 savloc
= sb_tell(sb
= sbp
);
185 retloc
= sb_tell(sb
);
186 sb_seek(sb
,savloc
,0);
190 /* GO (forward) to Next Line of specified sbbuf - returns 0 if stopped at EOF
191 * before an EOL is seen. */
194 { register SBBUF
*sb
;
199 while((c
= sb_getc(sb
)) != EOF
)
200 { if(c
== LF
) /* Possible EOL? */
201 { sb_backc(sb
); /* See if prev char was CR */
202 if((c
= sb_rgetc(sb
)) != EOF
)
204 sb_getc(sb
); /* Must restore position */
205 if(c
== CR
) /* Now test for CR */
206 return(1); /* Won, CR-LF! */
211 while((c
= sb_getc(sb
)) != EOF
)
217 /* GO (forward) to End Of Line of specified sbbuf - returns 0 if stopped at
218 * EOF before an EOL is seen. */
221 { register SBBUF
*sb
;
226 while((c
= sb_getc(sb
)) != EOF
)
227 { if(c
== LF
) /* Possible EOL? */
228 { sb_backc(sb
); /* See if prev char was CR */
229 if((c
= sb_rgetc(sb
)) == CR
)
230 return(1); /* Won, CR-LF! */
231 if(c
!= EOF
) /* No, must restore position */
232 sb_getc(sb
); /* Skip over */
233 sb_getc(sb
); /* Skip over LF */
238 while((c
= sb_getc(sb
)) != EOF
)
246 /* GO (backward) to Beg Of Line of specified sbbuf - returns 0 if stopped
251 { register SBBUF
*sb
;
256 while((c
= sb_rgetc(sb
)) != EOF
)
257 { if(c
== LF
) /* Possible EOL? */
258 { if((c
= sb_rgetc(sb
)) == CR
)
259 { sb_getc(sb
); /* Won, CR-LF! */
260 sb_getc(sb
); /* Move back */
263 if(c
!= EOF
) /* No, must restore position */
264 sb_getc(sb
); /* Undo the rgetc */
269 while((c
= sb_rgetc(sb
)) != EOF
)
277 /* GO (backward) to Previous Line of specified sbbuf - returns 0 if stopped
278 * at EOF before an EOL is seen (i.e. if already on 1st line of buffer)
282 { register SBBUF
*sb
;
287 while((c
= sb_rgetc(sb
)) != EOF
)
288 { if(c
== LF
) /* Possible EOL? */
289 { if((c
= sb_rgetc(sb
)) == CR
)
291 return(1); /* Won! */
293 if(c
!= EOF
) /* No, must restore position */
294 sb_getc(sb
); /* Undo the rgetc */
299 while((c
= sb_rgetc(sb
)) != EOF
)
302 return(1); /* Won! */
309 ex_blen(sbp
) /* Return length of specified sbbuf */
312 return(sb_tell(sbp
)+sb_ztell(sbp
));
315 /* Miscellaneous stuff */
317 /* E_GOFWSP() - Forward over whitespace */
320 while((c
= e_getc()) == SP
|| c
== TAB
);
321 if(c
!= EOF
) e_backc();
324 /* E_GOBWSP() - Backward over whitespace */
327 while((c
= e_rgetc()) == SP
|| c
== TAB
);
328 if(c
!= EOF
) e_getc();
332 /* E_GOLINE(n) - Goes N lines forward (or backward).
333 ** If N == 0, goes to beginning of current line.
334 ** Returns 0 if hit EOF.
340 { do { if(!e_gonl()) return(0); }
345 do { if(!e_gopl()) return(0); }
348 else e_gobol(); /* arg of 0 */
352 /* E_LBLANKP() - Returns true if all characters in rest of line are blank.
353 * Moves to beginning of next line as side effect, unless fails.
357 for(;;) switch(e_getc())
362 case LF
: /* Normally drop thru to return 1 as for EOF */
366 if((c
= e_rgetc()) != EOF
) /* Get prev char */
369 if(c
!= CR
) /* Now examine */
370 continue; /* Not CR-LF, go on */
371 } /* Else drop thru to return win */
378 /* Never drops out */
393 { register SBBUF
*sb
;
403 /* BOLEQ - Returns TRUE if 2 dots are on the same line
404 * (i.e. have the same Beg-Of-Line)
408 { return( (ex_boldot(CURSBB
,dot1
) == ex_boldot(CURSBB
,dot2
)));
424 s
= dottoa(s
, val
/10);
425 *s
++ = '0' + (int)(val
%10);
431 /* Paragraph utilities */
433 #if FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA
436 extern char *fill_prefix
; /* Defined in eefill.c for now */
437 extern int fill_plen
; /* Ditto */
441 int para_mode
= PARABLOCK
; /* eexcmd.c only other file that refs this */
442 #endif /*ICONOGRAPHICS*/
445 /* Go to beginning of paragraph */
452 while((c
= e_rgetc()) != EOF
)
453 if(c
== LF
) /* Went past line? */
454 { e_getc(); /* Back up and check */
457 if(tstfillp(fill_plen
))
458 { e_igoff(-(fill_plen
+1));
466 if (para_mode
== PARABLOCK
)
470 if (para_mode
== PARALINE
)
474 if(c_pwsp(e_peekc())) /* Check 1st chr for wsp */
475 break; /* If wsp, done */
476 #endif /*ICONOGRAPHICS*/
477 e_rgetc(); /* Nope, continue */
479 if((c
= e_peekc()) == '.' || c
== '-')
481 if(e_dot() >= savdot
)
486 /* Go to end of paragraph */
490 e_gobol(); /* First go to beg of cur line */
492 while((c
= e_getc()) != EOF
)
496 if(fill_plen
) /* If Fill Prefix is defined */
497 if(tstfillp(fill_plen
)) /* then must start with it */
499 else break; /* or else we're done */
502 if (para_mode
== PARABLOCK
)
503 if (e_peekc () == LF
)
506 if (para_mode
== PARALINE
)
507 if (c_wsp (e_peekc ()))
510 if(c_pwsp(e_peekc()))
512 #endif /*-ICONOGRAPHICS*/
517 int (*rpos
)(), (*rneg
)();
519 register int (*rtn
)();
535 while(c_wsp(c
= e_getc()));
536 if(c
!= EOF
) e_backc();
540 while(c_wsp(c
= e_rgetc()));
541 if(c
!= EOF
) e_getc();
549 if(c
== SP
|| c
== TAB
|| c
== LF
|| c
== FF
)
557 if(c
== '.' || c
== '-')
562 #endif /* FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA */
564 /* Word function auxiliaries */
566 /* Returns true if this character is a delimiter. */
569 { static int delim_tab
[] =
571 0177777, 0177777, /* All controls */
572 0177777, 0176000, /* All punct but 0-9 */
573 0000001, 0074000, /* All punct but A-Z and _ */
574 0000001, 0174000 /* All punct but a-z */
576 return (delim_tab
[c
>> 4] & (1 << (c
& 017)));
580 register chroff
*adot
;
597 { chroff savdot
, retdot
;
607 { register int (*gch
)(), c
, cnt
;
608 int e_getc(), e_rgetc();
614 gch
= e_getc
; /* Forward routine */
616 { gch
= e_rgetc
; /* Backward routine */
620 { ret_dot
= e_dot(); /* Remember dot for last word found */
621 while((c
= (*gch
)()) != EOF
&& delimp(c
));
623 { e_go(ret_dot
); /* Use last word found */
626 while((c
= (*gch
)()) != EOF
&& !delimp(c
));
629 if(n
< 0) e_getc(); else e_backc();
635 e_search(mstr
,mlen
,backwards
)
639 { register SBBUF
*sb
;
646 register int caseless
= (cur_buf
->b_flags
& B_TEXTMODE
);
649 sb
= (SBBUF
*) cur_buf
;
651 { /* Search forwards */
653 while((c
= sb_getc(sb
)) != EOF
)
656 if((!caseless
&& c
!= *cp
) ||
657 (caseless
&& upcase(c
) != upcase(*cp
))) continue;
659 if(c
!= *cp
) continue;
668 if ((!caseless
&& c1
!= c
) ||
669 (caseless
&& upcase(c1
) != upcase(c
)))
671 if(*cp
++ != (c
= e_getc()))
673 { if(c
== EOF
) return(0);
674 sb_seek(sb
,(chroff
)(cnt
-mlen
),1);
682 { /* Search backwards */
684 savcp
= mstr
+ scnt
; /* Point to end of string */
687 while((c
= sb_rgetc(sb
)) != EOF
)
690 if((!caseless
&& c
!= *cp
) ||
691 (caseless
&& upcase(c
) != upcase(*cp
))) continue;
693 if(c
!= *cp
) continue;
696 if((cnt
= scnt
) == 0) return(1);
702 if ((!caseless
&& c1
!= c
) ||
703 (caseless
&& upcase(c1
) != upcase(c
)))
705 if(*cp
-- != (c
= e_rgetc()))
707 { if(c
== EOF
) return(0);
708 sb_seek(sb
,(chroff
)(mlen
-cnt
),1);
716 return(0); /* Failed */