re-enable munmap().
[minix.git] / commands / elle / eeedit.c
blobbda677814a6df7e0722c1634beab84c7849c4312
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.
5 */
6 /* EEEDIT - E-type routines */
8 #include "elle.h"
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 */
23 { ex_reset(CURSBB);
24 cur_dot = 0;
27 /* Basic functions - apply SB routines to current buffer.
28 * There is some optimization here which knows that certain SB functions
29 * are macros.
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 */
41 { register SBBUF *sb;
42 sb = CURSBB; /* Macro: use reg */
43 return(sb_getc(sb));
45 e_backc() /* Move 1 char backward */
46 { register SBBUF *sb;
47 sb = CURSBB; /* Macro: use reg */
48 sb_backc(sb); /* No value returned */
50 e_putc(c) /* Insert/write 1 char forward */
51 char c;
52 { register SBBUF *sb;
53 sb = CURSBB; /* Macro: use reg */
54 return(sb_putc(sb, c));
56 e_peekc() /* Read 1 char forward (no move) */
57 { register SBBUF *sb;
58 sb = CURSBB; /* Macro: use reg */
59 return(sb_peekc(sb));
61 e_ovwc(ch) /* Overwrite 1 char forward */
62 char ch;
64 sb_setovw(CURSBB); /* Turn on overwrite mode */
65 e_putc(ch);
66 sb_clrovw(CURSBB); /* Turn off overwrite mode */
69 SBSTR *
70 e_copyn(off) /* Copy N chars forward/backward, return SD to sbstring */
71 chroff off;
72 { return(sb_cpyn(CURSBB,off));
74 e_deln(off) /* Delete N chars forward/backward */
75 chroff off;
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.
82 e_setcur()
83 { cur_dot = e_dot();
85 e_gosetcur(dot) /* Go to specified dot and set cur_dot as well */
86 chroff dot;
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. */
103 chroff dot;
104 { return(sb_seek(CURSBB,dot,0));
106 e_igoff(ioff) /* Move (int) N chars forward/backward */
107 int ioff;
108 { return(sb_seek(CURSBB,(chroff)ioff,1));
111 e_goff(off) /* Move (full) N chars forward/backward */
112 chroff off;
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 */
131 chroff
132 e_alldot(sbp,rtn) /* Auxiliary for above stuff */
133 SBBUF *sbp;
134 int (*rtn)();
135 { return(ex_alldot(sbp,rtn,e_dot()));
138 /* E_BLEN - Return length of current buffer */
139 chroff
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 */
147 ex_reset(b)
148 struct buffer *b;
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 */
154 chroff loc;
155 SBBUF *sbp;
156 { return(sb_seek(sbp,loc,0));
159 chroff
160 ex_dot(sbp) /* Return current position in specified sbbuf */
161 SBBUF *sbp;
163 return(sb_tell(sbp));
167 chroff
168 ex_boldot(sbp,dot) /* Return dot for BOL of specified sbbuf */
169 SBBUF *sbp;
170 chroff dot;
171 { return(ex_alldot(sbp,ex_gobol,dot));
174 chroff
175 ex_alldot(sbp,rtn,dot) /* Auxiliary for some e_ stuff */
176 SBBUF *sbp;
177 int (*rtn)();
178 chroff dot;
179 { register SBBUF *sb;
180 chroff savloc, retloc;
182 savloc = sb_tell(sb = sbp);
183 sb_seek(sb,dot,0);
184 (*rtn)(sb);
185 retloc = sb_tell(sb);
186 sb_seek(sb,savloc,0);
187 return(retloc);
190 /* GO (forward) to Next Line of specified sbbuf - returns 0 if stopped at EOF
191 * before an EOL is seen. */
192 ex_gonl(sbp)
193 SBBUF *sbp;
194 { register SBBUF *sb;
195 register int c;
196 sb = sbp;
197 #if FX_EOLMODE
198 if(eolcrlf(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)
203 sb_getc(sb);
204 sb_getc(sb); /* Must restore position */
205 if(c == CR) /* Now test for CR */
206 return(1); /* Won, CR-LF! */
209 else
210 #endif
211 while((c = sb_getc(sb)) != EOF)
212 if(c == LF)
213 return(1);
214 return(0);
217 /* GO (forward) to End Of Line of specified sbbuf - returns 0 if stopped at
218 * EOF before an EOL is seen. */
219 ex_goeol(sbp)
220 SBBUF *sbp;
221 { register SBBUF *sb;
222 register int c;
223 sb = sbp;
224 #if FX_EOLMODE
225 if(eolcrlf(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 */
236 else
237 #endif
238 while((c = sb_getc(sb)) != EOF)
239 if(c == LF)
240 { sb_backc(sb);
241 return(1);
243 return(0);
246 /* GO (backward) to Beg Of Line of specified sbbuf - returns 0 if stopped
247 * at EOF
249 ex_gobol(sbp)
250 SBBUF *sbp;
251 { register SBBUF *sb;
252 register int c;
253 sb = sbp;
254 #if FX_EOLMODE
255 if(eolcrlf(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 */
261 return(1);
263 if(c != EOF) /* No, must restore position */
264 sb_getc(sb); /* Undo the rgetc */
267 else
268 #endif
269 while((c = sb_rgetc(sb)) != EOF)
270 if(c == LF)
271 { sb_getc(sb);
272 return(1);
274 return(0);
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)
280 ex_gopl(sbp)
281 SBBUF *sbp;
282 { register SBBUF *sb;
283 register int c;
284 sb = sbp;
285 #if FX_EOLMODE
286 if(eolcrlf(sb))
287 while((c = sb_rgetc(sb)) != EOF)
288 { if(c == LF) /* Possible EOL? */
289 { if((c = sb_rgetc(sb)) == CR)
290 { ex_gobol(sb);
291 return(1); /* Won! */
293 if(c != EOF) /* No, must restore position */
294 sb_getc(sb); /* Undo the rgetc */
297 else
298 #endif
299 while((c = sb_rgetc(sb)) != EOF)
300 if(c == LF)
301 { ex_gobol(sb);
302 return(1); /* Won! */
304 return(0);
308 chroff
309 ex_blen(sbp) /* Return length of specified sbbuf */
310 SBBUF *sbp;
312 return(sb_tell(sbp)+sb_ztell(sbp));
315 /* Miscellaneous stuff */
317 /* E_GOFWSP() - Forward over whitespace */
318 e_gofwsp()
319 { register int c;
320 while((c = e_getc()) == SP || c == TAB);
321 if(c != EOF) e_backc();
324 /* E_GOBWSP() - Backward over whitespace */
325 e_gobwsp()
326 { register int c;
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.
336 e_goline(i)
337 register int i;
339 if(i > 0)
340 { do { if(!e_gonl()) return(0); }
341 while(--i);
343 else if(i < 0)
344 { i = -i;
345 do { if(!e_gopl()) return(0); }
346 while(--i);
348 else e_gobol(); /* arg of 0 */
349 return 1;
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.
355 e_lblankp()
356 { register int c;
357 for(;;) switch(e_getc())
359 case SP:
360 case TAB:
361 continue;
362 case LF: /* Normally drop thru to return 1 as for EOF */
363 #if FX_EOLMODE
364 if(eolcrlf(cur_buf))
365 { e_rgetc();
366 if((c = e_rgetc()) != EOF) /* Get prev char */
367 e_getc();
368 e_getc();
369 if(c != CR) /* Now examine */
370 continue; /* Not CR-LF, go on */
371 } /* Else drop thru to return win */
372 #endif
373 case EOF:
374 return(1);
375 default:
376 return(0);
378 /* Never drops out */
382 e_insn(ch, cnt)
383 int ch;
384 int cnt;
385 { register int i;
386 if((i = cnt) > 0)
387 do { e_putc(ch);
388 } while(--i);
391 e_sputz(acp)
392 char *acp;
393 { register SBBUF *sb;
394 register char *cp;
395 register int c;
396 if(cp = acp)
397 { sb = CURSBB;
398 while(c = *cp++)
399 sb_putc(sb,c);
403 /* BOLEQ - Returns TRUE if 2 dots are on the same line
404 * (i.e. have the same Beg-Of-Line)
406 boleq(dot1,dot2)
407 chroff dot1,dot2;
408 { return( (ex_boldot(CURSBB,dot1) == ex_boldot(CURSBB,dot2)));
412 char *
413 dottoa(str,val)
414 char *str;
415 chroff val;
416 { register char *s;
418 s = str;
419 if(val < 0)
420 { *s++ = '-';
421 val = -val;
423 if(val >= 10)
424 s = dottoa(s, val/10);
425 *s++ = '0' + (int)(val%10);
426 *s = 0;
427 return(s);
431 /* Paragraph utilities */
433 #if FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA
435 #if FX_SFPREF
436 extern char *fill_prefix; /* Defined in eefill.c for now */
437 extern int fill_plen; /* Ditto */
438 #endif /*FX_SFPREF*/
440 #if ICONOGRAPHICS
441 int para_mode = PARABLOCK; /* eexcmd.c only other file that refs this */
442 #endif /*ICONOGRAPHICS*/
445 /* Go to beginning of paragraph */
446 e_gobpa()
447 { register int c;
448 chroff savdot;
450 savdot = e_dot();
451 e_bwsp();
452 while((c = e_rgetc()) != EOF)
453 if(c == LF) /* Went past line? */
454 { e_getc(); /* Back up and check */
455 #if FX_SFPREF
456 if(fill_plen)
457 if(tstfillp(fill_plen))
458 { e_igoff(-(fill_plen+1));
459 continue;
461 else break;
462 #endif /*FX_SFPREF*/
463 #if ICONOGRAPHICS
464 c = e_peekc ();
466 if (para_mode == PARABLOCK)
467 if (c == LF)
468 break;
470 if (para_mode == PARALINE)
471 if (c_wsp (c))
472 break;
473 #else
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 == '-')
480 { e_gonl();
481 if(e_dot() >= savdot)
482 e_gopl();
486 /* Go to end of paragraph */
487 e_goepa()
488 { register int c;
490 e_gobol(); /* First go to beg of cur line */
491 e_fwsp();
492 while((c = e_getc()) != EOF)
493 if (c == LF)
495 #if FX_SFPREF
496 if(fill_plen) /* If Fill Prefix is defined */
497 if(tstfillp(fill_plen)) /* then must start with it */
498 continue;
499 else break; /* or else we're done */
500 #endif /*FX_SFPREF*/
501 #if ICONOGRAPHICS
502 if (para_mode == PARABLOCK)
503 if (e_peekc () == LF)
504 break;
506 if (para_mode == PARALINE)
507 if (c_wsp (e_peekc ()))
508 break;
509 #else
510 if(c_pwsp(e_peekc()))
511 break;
512 #endif /*-ICONOGRAPHICS*/
516 exp_do(rpos, rneg)
517 int (*rpos)(), (*rneg)();
518 { register int e;
519 register int (*rtn)();
521 if((e = exp) == 0)
522 return;
523 rtn = rpos;
524 if(e < 0)
525 { rtn = rneg;
526 e = -e;
528 do { (*rtn)();
529 } while(--e);
533 e_fwsp()
534 { register int c;
535 while(c_wsp(c = e_getc()));
536 if(c != EOF) e_backc();
538 e_bwsp()
539 { register int c;
540 while(c_wsp(c = e_rgetc()));
541 if(c != EOF) e_getc();
545 c_wsp(ch)
546 int ch;
547 { register int c;
548 c = ch;
549 if(c == SP || c == TAB || c == LF || c == FF)
550 return(1);
551 return(0);
553 c_pwsp(ch)
554 int ch;
555 { register int c;
556 c = ch;
557 if(c == '.' || c == '-')
558 return(1);
559 return(c_wsp(c));
562 #endif /* FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA */
564 /* Word function auxiliaries */
566 /* Returns true if this character is a delimiter. */
567 delimp(c)
568 int c;
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)));
579 e_wding(adot,n)
580 register chroff *adot;
581 int n;
582 { chroff savdot;
583 savdot = e_dot();
584 e_gowd(n);
585 *adot = e_dot();
586 e_go(savdot);
587 if(*adot == savdot)
588 { ring_bell();
589 return(0);
591 return(1);
593 chroff
594 e_wdot(dot,n)
595 chroff dot;
596 int n;
597 { chroff savdot, retdot;
598 savdot = e_dot();
599 e_go(dot);
600 e_gowd(n);
601 retdot = e_dot();
602 e_go(savdot);
603 return(retdot);
605 e_gowd(n)
606 int n;
607 { register int (*gch)(), c, cnt;
608 int e_getc(), e_rgetc();
609 chroff ret_dot;
611 if((cnt = n) == 0)
612 return;
613 if(cnt > 0)
614 gch = e_getc; /* Forward routine */
615 else
616 { gch = e_rgetc; /* Backward routine */
617 cnt = -cnt;
620 { ret_dot = e_dot(); /* Remember dot for last word found */
621 while((c = (*gch)()) != EOF && delimp(c));
622 if(c == EOF)
623 { e_go(ret_dot); /* Use last word found */
624 break;
626 while((c = (*gch)()) != EOF && !delimp(c));
627 if(c == EOF)
628 break;
629 if(n < 0) e_getc(); else e_backc();
630 } while(--cnt);
633 /* Searching */
635 e_search(mstr,mlen,backwards)
636 char *mstr;
637 int mlen;
638 int backwards;
639 { register SBBUF *sb;
640 register char *cp;
641 register int c;
642 char *savcp;
643 int cnt, scnt;
644 #if IMAGEN
645 register int c1;
646 register int caseless = (cur_buf->b_flags & B_TEXTMODE);
647 #endif /*IMAGEN*/
649 sb = (SBBUF *) cur_buf;
650 if (!backwards)
651 { /* Search forwards */
652 sfwd: cp = mstr;
653 while((c = sb_getc(sb)) != EOF)
655 #if IMAGEN
656 if((!caseless && c != *cp) ||
657 (caseless && upcase(c) != upcase(*cp))) continue;
658 #else
659 if(c != *cp) continue;
660 #endif /*-IMAGEN*/
661 cp++;
662 cnt = mlen;
663 while(--cnt > 0)
665 #if IMAGEN
666 c1 = *cp++;
667 c = e_getc();
668 if ((!caseless && c1 != c) ||
669 (caseless && upcase(c1) != upcase(c)))
670 #else
671 if(*cp++ != (c = e_getc()))
672 #endif /*-IMAGEN*/
673 { if(c == EOF) return(0);
674 sb_seek(sb,(chroff)(cnt-mlen),1);
675 goto sfwd;
678 return(1);
681 else
682 { /* Search backwards */
683 scnt = mlen - 1;
684 savcp = mstr + scnt; /* Point to end of string */
686 sbck: cp = savcp;
687 while((c = sb_rgetc(sb)) != EOF)
689 #if IMAGEN
690 if((!caseless && c != *cp) ||
691 (caseless && upcase(c) != upcase(*cp))) continue;
692 #else
693 if(c != *cp) continue;
694 #endif /*-IMAGEN*/
695 cp--;
696 if((cnt = scnt) == 0) return(1);
699 #if IMAGEN
700 c1 = *cp--;
701 c = e_rgetc();
702 if ((!caseless && c1 != c) ||
703 (caseless && upcase(c1) != upcase(c)))
704 #else
705 if(*cp-- != (c = e_rgetc()))
706 #endif /*-IMAGEN*/
707 { if(c == EOF) return(0);
708 sb_seek(sb,(chroff)(mlen-cnt),1);
709 goto sbck;
712 while(--cnt);
713 return(1);
716 return(0); /* Failed */