source: trunk/minix/commands/elle/eeedit.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 15.2 KB
Line 
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 */
7
8#include "elle.h"
9
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.
15 *
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.
18 */
19
20#define CURSBB (SBBUF *)cur_buf /* Shorthand for current SB buffer */
21
22e_reset() /* Reset current buffer */
23{ ex_reset(CURSBB);
24 cur_dot = 0;
25}
26
27/* Basic functions - apply SB routines to current buffer.
28 * There is some optimization here which knows that certain SB functions
29 * are macros.
30 */
31e_rgetc() /* Read/move 1 char backward */
32{ return(sb_rgetc((CURSBB)));
33}
34e_rdelc() /* Delete 1 char backward */
35{ return(sb_rdelc((CURSBB)));
36}
37e_delc() /* Delete 1 char forward */
38{ return(sb_deln(CURSBB,(chroff)1));
39}
40e_getc() /* Read/move 1 char forward */
41{ register SBBUF *sb;
42 sb = CURSBB; /* Macro: use reg */
43 return(sb_getc(sb));
44}
45e_backc() /* Move 1 char backward */
46{ register SBBUF *sb;
47 sb = CURSBB; /* Macro: use reg */
48 sb_backc(sb); /* No value returned */
49}
50e_putc(c) /* Insert/write 1 char forward */
51char c;
52{ register SBBUF *sb;
53 sb = CURSBB; /* Macro: use reg */
54 return(sb_putc(sb, c));
55}
56e_peekc() /* Read 1 char forward (no move) */
57{ register SBBUF *sb;
58 sb = CURSBB; /* Macro: use reg */
59 return(sb_peekc(sb));
60}
61e_ovwc(ch) /* Overwrite 1 char forward */
62char ch;
63{
64 sb_setovw(CURSBB); /* Turn on overwrite mode */
65 e_putc(ch);
66 sb_clrovw(CURSBB); /* Turn off overwrite mode */
67}
68
69SBSTR *
70e_copyn(off) /* Copy N chars forward/backward, return SD to sbstring */
71chroff off;
72{ return(sb_cpyn(CURSBB,off));
73}
74e_deln(off) /* Delete N chars forward/backward */
75chroff off;
76{ return(sb_deln(CURSBB, off));
77}
78
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.
81 */
82e_setcur()
83{ cur_dot = e_dot();
84}
85e_gosetcur(dot) /* Go to specified dot and set cur_dot as well */
86chroff dot;
87{ sb_seek(CURSBB,dot,0);
88 e_setcur(); /* Not cur_dot = dot since want canonicalization */
89}
90
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.
97 */
98
99e_gocur() { return(e_go(cur_dot)); } /* Move to cur_dot */
100e_gobob() { return(e_go((chroff) 0)); } /* Move to Beg Of Buffer */
101e_goeob() { return(sb_seek(CURSBB,(chroff)0,2)); } /* Move to End Of Buffer */
102e_go(dot) /* Move to specified location. */
103chroff dot;
104{ return(sb_seek(CURSBB,dot,0));
105}
106e_igoff(ioff) /* Move (int) N chars forward/backward */
107int ioff;
108{ return(sb_seek(CURSBB,(chroff)ioff,1));
109}
110
111e_goff(off) /* Move (full) N chars forward/backward */
112chroff off;
113{ return(sb_seek(CURSBB,off,1));
114}
115
116int ex_gonl(), ex_gopl(), ex_gobol(), ex_goeol();
117
118e_gobol() { return(ex_gobol(CURSBB)); } /* Move to beg of this line */
119e_goeol() { return(ex_goeol(CURSBB)); } /* Move to end of this line */
120e_gonl() { return(ex_gonl(CURSBB)); } /* Move to beg of next line */
121e_gopl() { return(ex_gopl(CURSBB)); } /* Move to beg of prev line */
122
123
124/* E_DOT() - Return current value of dot. */
125chroff e_dot() { return(sb_tell(CURSBB)); } /* Current pos */
126chroff e_nldot() { return(e_alldot(CURSBB,ex_gonl)); } /* Beg of next line */
127chroff e_pldot() { return(e_alldot(CURSBB,ex_gopl)); } /* Beg of prev line */
128chroff e_boldot(){ return(e_alldot(CURSBB,ex_gobol));} /* Beg of this line */
129chroff e_eoldot(){ return(e_alldot(CURSBB,ex_goeol));} /* End of this line */
130
131chroff
132e_alldot(sbp,rtn) /* Auxiliary for above stuff */
133SBBUF *sbp;
134int (*rtn)();
135{ return(ex_alldot(sbp,rtn,e_dot()));
136}
137
138/* E_BLEN - Return length of current buffer */
139chroff
140e_blen() { return(ex_blen(CURSBB)); }
141
142
143/* EX_ routines - similar to E_ but take a buffer/sbbuf argument
144 * instead of assuming current buffer.
145 */
146
147/* EX_RESET - Reset a given buffer */
148ex_reset(b)
149struct buffer *b;
150{ sbs_del(sb_close((SBBUF *)b));
151 sb_open((SBBUF *)b,(SBSTR *)0);
152}
153
154ex_go(sbp,loc) /* Move to given dot in specified sbbuf */
155chroff loc;
156SBBUF *sbp;
157{ return(sb_seek(sbp,loc,0));
158}
159
160chroff
161ex_dot(sbp) /* Return current position in specified sbbuf */
162SBBUF *sbp;
163{
164 return(sb_tell(sbp));
165}
166
167
168chroff
169ex_boldot(sbp,dot) /* Return dot for BOL of specified sbbuf */
170SBBUF *sbp;
171chroff dot;
172{ return(ex_alldot(sbp,ex_gobol,dot));
173}
174
175chroff
176ex_alldot(sbp,rtn,dot) /* Auxiliary for some e_ stuff */
177SBBUF *sbp;
178int (*rtn)();
179chroff dot;
180{ register SBBUF *sb;
181 chroff savloc, retloc;
182
183 savloc = sb_tell(sb = sbp);
184 sb_seek(sb,dot,0);
185 (*rtn)(sb);
186 retloc = sb_tell(sb);
187 sb_seek(sb,savloc,0);
188 return(retloc);
189}
190
191/* GO (forward) to Next Line of specified sbbuf - returns 0 if stopped at EOF
192 * before an EOL is seen. */
193ex_gonl(sbp)
194SBBUF *sbp;
195{ register SBBUF *sb;
196 register int c;
197 sb = sbp;
198#if FX_EOLMODE
199 if(eolcrlf(sb))
200 while((c = sb_getc(sb)) != EOF)
201 { if(c == LF) /* Possible EOL? */
202 { sb_backc(sb); /* See if prev char was CR */
203 if((c = sb_rgetc(sb)) != EOF)
204 sb_getc(sb);
205 sb_getc(sb); /* Must restore position */
206 if(c == CR) /* Now test for CR */
207 return(1); /* Won, CR-LF! */
208 }
209 }
210 else
211#endif
212 while((c = sb_getc(sb)) != EOF)
213 if(c == LF)
214 return(1);
215 return(0);
216}
217
218/* GO (forward) to End Of Line of specified sbbuf - returns 0 if stopped at
219 * EOF before an EOL is seen. */
220ex_goeol(sbp)
221SBBUF *sbp;
222{ register SBBUF *sb;
223 register int c;
224 sb = sbp;
225#if FX_EOLMODE
226 if(eolcrlf(sb))
227 while((c = sb_getc(sb)) != EOF)
228 { if(c == LF) /* Possible EOL? */
229 { sb_backc(sb); /* See if prev char was CR */
230 if((c = sb_rgetc(sb)) == CR)
231 return(1); /* Won, CR-LF! */
232 if(c != EOF) /* No, must restore position */
233 sb_getc(sb); /* Skip over */
234 sb_getc(sb); /* Skip over LF */
235 }
236 }
237 else
238#endif
239 while((c = sb_getc(sb)) != EOF)
240 if(c == LF)
241 { sb_backc(sb);
242 return(1);
243 }
244 return(0);
245}
246
247/* GO (backward) to Beg Of Line of specified sbbuf - returns 0 if stopped
248 * at EOF
249 */
250ex_gobol(sbp)
251SBBUF *sbp;
252{ register SBBUF *sb;
253 register int c;
254 sb = sbp;
255#if FX_EOLMODE
256 if(eolcrlf(sb))
257 while((c = sb_rgetc(sb)) != EOF)
258 { if(c == LF) /* Possible EOL? */
259 { if((c = sb_rgetc(sb)) == CR)
260 { sb_getc(sb); /* Won, CR-LF! */
261 sb_getc(sb); /* Move back */
262 return(1);
263 }
264 if(c != EOF) /* No, must restore position */
265 sb_getc(sb); /* Undo the rgetc */
266 }
267 }
268 else
269#endif
270 while((c = sb_rgetc(sb)) != EOF)
271 if(c == LF)
272 { sb_getc(sb);
273 return(1);
274 }
275 return(0);
276}
277
278/* GO (backward) to Previous Line of specified sbbuf - returns 0 if stopped
279 * at EOF before an EOL is seen (i.e. if already on 1st line of buffer)
280 */
281ex_gopl(sbp)
282SBBUF *sbp;
283{ register SBBUF *sb;
284 register int c;
285 sb = sbp;
286#if FX_EOLMODE
287 if(eolcrlf(sb))
288 while((c = sb_rgetc(sb)) != EOF)
289 { if(c == LF) /* Possible EOL? */
290 { if((c = sb_rgetc(sb)) == CR)
291 { ex_gobol(sb);
292 return(1); /* Won! */
293 }
294 if(c != EOF) /* No, must restore position */
295 sb_getc(sb); /* Undo the rgetc */
296 }
297 }
298 else
299#endif
300 while((c = sb_rgetc(sb)) != EOF)
301 if(c == LF)
302 { ex_gobol(sb);
303 return(1); /* Won! */
304 }
305 return(0);
306}
307
308
309chroff
310ex_blen(sbp) /* Return length of specified sbbuf */
311SBBUF *sbp;
312{
313 return(sb_tell(sbp)+sb_ztell(sbp));
314}
315
316
317/* Miscellaneous stuff */
318
319/* E_GOFWSP() - Forward over whitespace */
320e_gofwsp()
321{ register int c;
322 while((c = e_getc()) == SP || c == TAB);
323 if(c != EOF) e_backc();
324}
325
326/* E_GOBWSP() - Backward over whitespace */
327e_gobwsp()
328{ register int c;
329 while((c = e_rgetc()) == SP || c == TAB);
330 if(c != EOF) e_getc();
331}
332
333
334/* E_GOLINE(n) - Goes N lines forward (or backward).
335** If N == 0, goes to beginning of current line.
336** Returns 0 if hit EOF.
337*/
338e_goline(i)
339register int i;
340{
341 if(i > 0)
342 { do { if(!e_gonl()) return(0); }
343 while(--i);
344 }
345 else if(i < 0)
346 { i = -i;
347 do { if(!e_gopl()) return(0); }
348 while(--i);
349 }
350 else e_gobol(); /* arg of 0 */
351 return 1;
352}
353
354/* E_LBLANKP() - Returns true if all characters in rest of line are blank.
355 * Moves to beginning of next line as side effect, unless fails.
356 */
357e_lblankp()
358{ register int c;
359 for(;;) switch(e_getc())
360 {
361 case SP:
362 case TAB:
363 continue;
364 case LF: /* Normally drop thru to return 1 as for EOF */
365#if FX_EOLMODE
366 if(eolcrlf(cur_buf))
367 { e_rgetc();
368 if((c = e_rgetc()) != EOF) /* Get prev char */
369 e_getc();
370 e_getc();
371 if(c != CR) /* Now examine */
372 continue; /* Not CR-LF, go on */
373 } /* Else drop thru to return win */
374#endif
375 case EOF:
376 return(1);
377 default:
378 return(0);
379 }
380 /* Never drops out */
381}
382
383
384
385e_insn(ch, cnt)
386int ch;
387int cnt;
388{ register int i;
389 if((i = cnt) > 0)
390 do { e_putc(ch);
391 } while(--i);
392}
393
394e_sputz(acp)
395char *acp;
396{ register SBBUF *sb;
397 register char *cp;
398 register int c;
399 if(cp = acp)
400 { sb = CURSBB;
401 while(c = *cp++)
402 sb_putc(sb,c);
403 }
404}
405
406/* BOLEQ - Returns TRUE if 2 dots are on the same line
407 * (i.e. have the same Beg-Of-Line)
408 */
409boleq(dot1,dot2)
410chroff dot1,dot2;
411{ return( (ex_boldot(CURSBB,dot1) == ex_boldot(CURSBB,dot2)));
412}
413
414
415char *
416dottoa(str,val)
417char *str;
418chroff val;
419{ register char *s;
420
421 s = str;
422 if(val < 0)
423 { *s++ = '-';
424 val = -val;
425 }
426 if(val >= 10)
427 s = dottoa(s, val/10);
428 *s++ = '0' + (int)(val%10);
429 *s = 0;
430 return(s);
431}
432
433
434
435/* Paragraph utilities */
436
437#if FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA
438
439#if FX_SFPREF
440extern char *fill_prefix; /* Defined in eefill.c for now */
441extern int fill_plen; /* Ditto */
442#endif /*FX_SFPREF*/
443
444#if ICONOGRAPHICS
445int para_mode = PARABLOCK; /* eexcmd.c only other file that refs this */
446#endif /*ICONOGRAPHICS*/
447
448
449/* Go to beginning of paragraph */
450e_gobpa()
451{ register int c;
452 chroff savdot;
453
454 savdot = e_dot();
455 e_bwsp();
456 while((c = e_rgetc()) != EOF)
457 if(c == LF) /* Went past line? */
458 { e_getc(); /* Back up and check */
459#if FX_SFPREF
460 if(fill_plen)
461 if(tstfillp(fill_plen))
462 { e_igoff(-(fill_plen+1));
463 continue;
464 }
465 else break;
466#endif /*FX_SFPREF*/
467#if ICONOGRAPHICS
468 c = e_peekc ();
469
470 if (para_mode == PARABLOCK)
471 if (c == LF)
472 break;
473
474 if (para_mode == PARALINE)
475 if (c_wsp (c))
476 break;
477#else
478 if(c_pwsp(e_peekc())) /* Check 1st chr for wsp */
479 break; /* If wsp, done */
480#endif /*ICONOGRAPHICS*/
481 e_rgetc(); /* Nope, continue */
482 }
483 if((c = e_peekc()) == '.' || c == '-')
484 { e_gonl();
485 if(e_dot() >= savdot)
486 e_gopl();
487 }
488}
489
490/* Go to end of paragraph */
491e_goepa()
492{ register int c;
493
494 e_gobol(); /* First go to beg of cur line */
495 e_fwsp();
496 while((c = e_getc()) != EOF)
497 if (c == LF)
498 {
499#if FX_SFPREF
500 if(fill_plen) /* If Fill Prefix is defined */
501 if(tstfillp(fill_plen)) /* then must start with it */
502 continue;
503 else break; /* or else we're done */
504#endif /*FX_SFPREF*/
505#if ICONOGRAPHICS
506 if (para_mode == PARABLOCK)
507 if (e_peekc () == LF)
508 break;
509
510 if (para_mode == PARALINE)
511 if (c_wsp (e_peekc ()))
512 break;
513#else
514 if(c_pwsp(e_peekc()))
515 break;
516#endif /*-ICONOGRAPHICS*/
517 }
518}
519
520exp_do(rpos, rneg)
521int (*rpos)(), (*rneg)();
522{ register int e;
523 register int (*rtn)();
524
525 if((e = exp) == 0)
526 return;
527 rtn = rpos;
528 if(e < 0)
529 { rtn = rneg;
530 e = -e;
531 }
532 do { (*rtn)();
533 } while(--e);
534}
535
536
537e_fwsp()
538{ register int c;
539 while(c_wsp(c = e_getc()));
540 if(c != EOF) e_backc();
541}
542e_bwsp()
543{ register int c;
544 while(c_wsp(c = e_rgetc()));
545 if(c != EOF) e_getc();
546}
547
548
549c_wsp(ch)
550int ch;
551{ register int c;
552 c = ch;
553 if(c == SP || c == TAB || c == LF || c == FF)
554 return(1);
555 return(0);
556}
557c_pwsp(ch)
558int ch;
559{ register int c;
560 c = ch;
561 if(c == '.' || c == '-')
562 return(1);
563 return(c_wsp(c));
564}
565
566#endif /* FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA */
567
568
569/* Word function auxiliaries */
570
571/* Returns true if this character is a delimiter. */
572delimp(c)
573int c;
574{ static int delim_tab[] =
575 {
576 0177777, 0177777, /* All controls */
577 0177777, 0176000, /* All punct but 0-9 */
578 0000001, 0074000, /* All punct but A-Z and _ */
579 0000001, 0174000 /* All punct but a-z */
580 };
581 return (delim_tab[c >> 4] & (1 << (c & 017)));
582}
583
584e_wding(adot,n)
585register chroff *adot;
586int n;
587{ chroff savdot;
588 savdot = e_dot();
589 e_gowd(n);
590 *adot = e_dot();
591 e_go(savdot);
592 if(*adot == savdot)
593 { ring_bell();
594 return(0);
595 }
596 return(1);
597}
598chroff
599e_wdot(dot,n)
600chroff dot;
601int n;
602{ chroff savdot, retdot;
603 savdot = e_dot();
604 e_go(dot);
605 e_gowd(n);
606 retdot = e_dot();
607 e_go(savdot);
608 return(retdot);
609}
610e_gowd(n)
611int n;
612{ register int (*gch)(), c, cnt;
613 int e_getc(), e_rgetc();
614 chroff ret_dot;
615
616 if((cnt = n) == 0)
617 return;
618 if(cnt > 0)
619 gch = e_getc; /* Forward routine */
620 else
621 { gch = e_rgetc; /* Backward routine */
622 cnt = -cnt;
623 }
624 do
625 { ret_dot = e_dot(); /* Remember dot for last word found */
626 while((c = (*gch)()) != EOF && delimp(c));
627 if(c == EOF)
628 { e_go(ret_dot); /* Use last word found */
629 break;
630 }
631 while((c = (*gch)()) != EOF && !delimp(c));
632 if(c == EOF)
633 break;
634 if(n < 0) e_getc(); else e_backc();
635 } while(--cnt);
636}
637
638
639/* Searching */
640
641e_search(mstr,mlen,backwards)
642char *mstr;
643int mlen;
644int backwards;
645{ register SBBUF *sb;
646 register char *cp;
647 register int c;
648 char *savcp;
649 int cnt, scnt;
650#if IMAGEN
651 register int c1;
652 register int caseless = (cur_buf->b_flags & B_TEXTMODE);
653#endif /*IMAGEN*/
654
655 sb = (SBBUF *) cur_buf;
656 if (!backwards)
657 { /* Search forwards */
658 sfwd: cp = mstr;
659 while((c = sb_getc(sb)) != EOF)
660 {
661#if IMAGEN
662 if((!caseless && c != *cp) ||
663 (caseless && upcase(c) != upcase(*cp))) continue;
664#else
665 if(c != *cp) continue;
666#endif /*-IMAGEN*/
667 cp++;
668 cnt = mlen;
669 while(--cnt > 0)
670 {
671#if IMAGEN
672 c1 = *cp++;
673 c = e_getc();
674 if ((!caseless && c1 != c) ||
675 (caseless && upcase(c1) != upcase(c)))
676#else
677 if(*cp++ != (c = e_getc()))
678#endif /*-IMAGEN*/
679 { if(c == EOF) return(0);
680 sb_seek(sb,(chroff)(cnt-mlen),1);
681 goto sfwd;
682 }
683 }
684 return(1);
685 }
686 }
687 else
688 { /* Search backwards */
689 scnt = mlen - 1;
690 savcp = mstr + scnt; /* Point to end of string */
691
692 sbck: cp = savcp;
693 while((c = sb_rgetc(sb)) != EOF)
694 {
695#if IMAGEN
696 if((!caseless && c != *cp) ||
697 (caseless && upcase(c) != upcase(*cp))) continue;
698#else
699 if(c != *cp) continue;
700#endif /*-IMAGEN*/
701 cp--;
702 if((cnt = scnt) == 0) return(1);
703 do
704 {
705#if IMAGEN
706 c1 = *cp--;
707 c = e_rgetc();
708 if ((!caseless && c1 != c) ||
709 (caseless && upcase(c1) != upcase(c)))
710#else
711 if(*cp-- != (c = e_rgetc()))
712#endif /*-IMAGEN*/
713 { if(c == EOF) return(0);
714 sb_seek(sb,(chroff)(mlen-cnt),1);
715 goto sbck;
716 }
717 }
718 while(--cnt);
719 return(1);
720 }
721 }
722 return(0); /* Failed */
723}
Note: See TracBrowser for help on using the repository browser.