home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 208_01 / e4.c < prev    next >
Text File  |  1987-10-13  |  5KB  |  251 lines

  1. /*
  2. HEADER:        CUG208;
  3. TITLE:        'e' for CP/M68K
  4. VERSION:    1.48+
  5.  
  6. DESCRIPTION:    "a screen editor";
  7.  
  8. KEYWORDS:    editor;
  9. SYSTEM:        CP/M68K, V1.2;
  10. FILENAME:    e/e4.c
  11. WARNINGS:    "the default value is for systems with 128K bytes
  12.          of memory or more";
  13. SEE-ALSO:    cpm68k.c, e68k.doc, CUG VOL 133;
  14. AUTHORS:    G.N.Gilbert('e'), J.W.Haefner(for DeSmet C on MSDOS and UNIX)
  15. CODER:        Yoshimasa Tsuji
  16. COMPILERS:    DRI C(Alcyon C) for CP/M68K;
  17. */
  18. /*
  19.     FUNCTIONS: findorrep,dofindrep,find
  20.     PURPOSE: perform find, alter and repeat commands
  21. */
  22.  
  23. # include "e.h"
  24.  
  25. findorrep()
  26. {
  27.     int  toend, global, i, count;
  28.     char c, *p;
  29.  
  30.     putmess("Find? ");
  31.     global=nocheck=toend=nocase=NO;
  32.     findir=1;
  33.     count=0;
  34.     c=scans(patt,FLIM);
  35.     if (replace) {
  36.         if (c == ESCKEY) return;
  37.         putmess("Alter to? ");
  38.  
  39.         c=scans(changeto,FLIM);
  40.     }
  41.     else if (!patt[0]) return;
  42.     if (c == CR) {
  43.         if (replace)
  44.             putmess("B|ackwards/|G|lobally/|T|o end (start)/|I|gnore case/|W|ithout asking/number|? ");
  45.         else putmess("B|ackwards/|I|gnore case/number of times|? ");
  46.         if (scans(opts,5) == ESCKEY) return;
  47.         for (i=0; (c=opts[i]); i++) {
  48.             switch(tolower(c)) {
  49.             case 'g' :
  50.                 global=YES;
  51.             case 't' :
  52.                 toend=YES;
  53.                 break;
  54.             case 'b' :
  55.                 findir= -1;
  56.                 break;
  57.             case 'w' :
  58.                 nocheck=YES;
  59.                 break;
  60.             case 'i' :
  61.                 nocase=YES;
  62.                 for (p=patt; *p; p++)
  63.                     *p=tolower(*p);
  64.                 break;
  65.             }
  66.             if (c >= '0' && c <= '9') count=count*10+c-'0';
  67.         }
  68.         if (!replace) {
  69.             global=NO;
  70.             toend=NO;
  71.         }
  72.         if (count == 0) {
  73.             if (toend) count=MAXINT;
  74.             else count=1;
  75.         }
  76.         if (global) {
  77.             findir=1;
  78.             moveline(1-cline);
  79.             sync(0);
  80.         }
  81.     }
  82.     else count=1;
  83.     dofindrep(count);
  84. }
  85.  
  86. dofindrep(count)
  87. int count;
  88. {
  89.     int cp, i, len;
  90.     char c;
  91.  
  92.     puttext();
  93.     do {
  94.         count--;
  95.         if (find() == FAIL) count=0;
  96.         else if (replace) {
  97.             if (nocheck) c='y';
  98.             else {
  99.                 gotoxy(EMPOS,0);
  100.                 putstr("     Replace |{|Y|/|N|}|? ");
  101.                 do {
  102.                     gotoxy(REPPOS,0);
  103.                     for (i=0; i < 10*CURSORWAIT; i++);
  104.                     resetcursor();
  105.                     for (i=0; i < 10*CURSORWAIT; i++);
  106.                 }
  107.                 while ((c=testlow()) != 'y' && c != 'n'
  108.                     && c != ESCKEY);
  109.             }
  110.             deleteline(EMPOS,0);
  111.             switch(c) {
  112.             case 'y' :
  113.                 if (strlen(text)+(len=strlen(patt)) >= LLIM) {
  114.                     error("Line would be too long");
  115.                     return;
  116.                 }
  117.                 for (cp=charn; (text[cp]=text[cp+len]); cp++);
  118.                 for (cp=strlen(text), len=strlen(changeto);
  119.                     cp >= charn; cp--)
  120.                         text[cp+len]=text[cp];
  121.                 for (i=0; (c=changeto[i]); i++) text[charn++]=c;
  122.                 altered=YES;
  123.                 puttext();
  124.                 rewrite(++cp,cursorx);
  125.                 sync(charn);
  126.                 break;
  127.             case ESCKEY:
  128.                 count=0;
  129.                 error("Search stopped");
  130.             case 'n' :
  131.                 movechar(findir);
  132.                 break;
  133.             }
  134.         }
  135.     }
  136.     while(count);
  137.     inbufp=0;
  138. }
  139.  
  140. /*find 'patt', searching back (findir== -1) or forwards (1) from
  141.  *      current line.  Return FAIL or YES, and set current line to
  142.  *      that containing pattern
  143.  */
  144. find()
  145. {
  146.     int fline, oldcharn, newcharn, interupt;
  147.     register int linecount, pos;
  148.     register char *s, pattch1, *p, *t;
  149.     char lcline[LLIM];
  150.  
  151.     if (!replace || repeat) movechar(findir);
  152.     fline=cline;
  153.     oldcharn=charn;
  154.     interupt=NO;
  155.     linecount= cline%100;
  156.     pattch1=patt[0];
  157.     gotoxy(WAITPOS,0);
  158.     if (findir == 1)
  159.         while (fline <= lastl) {
  160.             if (linecount++ == 100) {
  161.                 linecount=1;
  162.                 ptlineno(fline);
  163.                 gotoxy(WAITPOS,0);
  164.                 if (testkey() == ESCKEY) {
  165.                     interupt=YES;
  166.                     goto interrupted;
  167.                 }
  168.             }
  169.             s=getline(fline)+charn;
  170.             if (nocase) {
  171.                 for (t=lcline; (*t=tolower(*s & NOPARITY));
  172.                             s++, t++);
  173.                     s=lcline;
  174.             }
  175.             if ( (pos=indexx(s,patt)) != FAIL) {
  176.                 charn+=pos;
  177.                 goto foundit;
  178.             }
  179.             fline++;
  180.             charn=0;
  181.         }
  182.     else
  183.         while (fline >= 1) {
  184.             if (linecount-- == 0) {
  185.                 linecount=99;
  186.                 ptlineno(fline);
  187.                 gotoxy(WAITPOS,0);
  188.                 if (testkey() == ESCKEY) {
  189.                     interupt=YES;
  190.                     goto interrupted;
  191.                 }
  192.             }
  193.             s=getline(fline);
  194.             if (nocase) {
  195.                 for (t=lcline; (*t=tolower(*s)); s++, t++);
  196.                 s=lcline;
  197.             }
  198.             for (; charn >= 0; charn--)
  199.                 if (*(p= &s[charn]) == pattch1) {
  200.                     for (t=patt+1,p++; *t && *p == *t; p++, t++);
  201.                     if (!*t) goto foundit;
  202.                 }
  203.             charn=strlen(getline(--fline))-1;
  204.         }
  205. interrupted:
  206.     charn=oldcharn;
  207.     if (!replace || repeat) movechar(-findir);
  208.     if (interupt) {
  209.         error("Search aborted");
  210.         ptlineno(cline);
  211.     }
  212.     else error("       Search fails");
  213.     return FAIL;
  214.  
  215. foundit:
  216.     newcharn=charn;
  217.     moveline(fline-cline);
  218.     sync(charn=newcharn);
  219.     return YES;
  220. }
  221.  
  222. static
  223. indexx(str,substr)
  224. char *str, *substr;
  225. /*
  226.  * Returns index of substr in str, or -1 if not found.
  227.  */
  228. {
  229.     register char *p, *q, *s;
  230.     register int c;
  231.     c = *substr;
  232.     p = str -1;
  233.  
  234.     for(;;){
  235.         do {
  236.             if( *++p == 0)    /* end of str?    */
  237.                 return (-1);    /* not found.    */
  238.         }
  239.         while (c != *p);
  240.  
  241.         q = p;        /* first char matched    */
  242.         s = substr;
  243.         do {
  244.             q++;
  245.             if(*++s == 0)    /* end of substr?    */
  246.                 return (int)(p - str);
  247.         }
  248.         while (*s == *q);    /* current char match?    */
  249.     }
  250. }
  251.