home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / newemacs / search.c < prev    next >
Text File  |  1979-12-31  |  8KB  |  363 lines

  1. /*
  2.  * The functions in this file
  3.  * implement commands that search in the
  4.  * forward and backward directions. There are
  5.  * no special characters in the search strings.
  6.  * Probably should have a regular expression
  7.  * search, or something like that.
  8.  */
  9. #include    <stdio.h>
  10. #include    "ed.h"
  11.  
  12. /*
  13.  * Search forward.
  14.  * Get a search string from the
  15.  * user, and search, beginning at ".",
  16.  * for the string. If found, reset the
  17.  * "." to be just after the match string,
  18.  * and [perhaps] repaint the display.
  19.  * Bound to "M-S".
  20.  */
  21. forwsearch(f, n)
  22. {
  23.     register LINE    *clp;
  24.     register int    cbo;
  25.     register LINE    *tlp;
  26.     register int    tbo;
  27.     register int    c;
  28.     register char    *pp;
  29.     register int    s;
  30.  
  31.     if ((s=readpattern("Search")) != TRUE)
  32.         return (s);
  33.     clp = curwp->w_dotp;
  34.     cbo = curwp->w_doto;
  35.     while (clp != curbp->b_linep) {
  36.         if (cbo == llength(clp)) {
  37.             clp = lforw(clp);
  38.             cbo = 0;
  39.             c   = '\n';
  40.         } else
  41.             c = lgetc(clp, cbo++);
  42.         if (eq(c, *pat)) {
  43.             tlp = clp;
  44.             tbo = cbo;
  45.             pp  = pat+1;
  46.             while (*pp) {
  47.                 if (tlp == curbp->b_linep)
  48.                     goto fail;
  49.                 if (tbo == llength(tlp)) {
  50.                     tlp = lforw(tlp);
  51.                     tbo = 0;
  52.                     c   = '\n';
  53.                 } else
  54.                     c = lgetc(tlp, tbo++);
  55.                 if (!eq(c, *pp++))
  56.                     goto fail;
  57.             }
  58.             curwp->w_dotp  = tlp;
  59.             curwp->w_doto  = tbo;
  60.             curwp->w_flag |= WFMOVE;
  61.             return (TRUE);
  62.         }
  63.     fail:    ;
  64.     }
  65.     mlwrite("Not found");
  66.     scr_co(0x07) ;
  67.     return (FALSE);
  68. }
  69.  
  70. /*
  71.  * Reverse search.
  72.  * Get a search string from the
  73.  * user, and search, starting at "."
  74.  * and proceeding toward the front of
  75.  * the buffer. If found "." is left
  76.  * pointing at the first character of
  77.  * the pattern [the last character that
  78.  * was matched]. Bound to "M-R".
  79.  */
  80. backsearch(f, n)
  81. {
  82.     register LINE    *clp;
  83.     register int    cbo;
  84.     register LINE    *tlp;
  85.     register int    tbo;
  86.     register int    c;
  87.     register char    *epp;
  88.     register char    *pp;
  89.     register int    s;
  90.  
  91.     if ((s=readpattern("Reverse search")) != TRUE)
  92.         return (s);
  93.     for (epp = pat; epp[1]; ++epp)
  94.         ;
  95.     clp = curwp->w_dotp;
  96.     cbo = curwp->w_doto;
  97.     for (;;) {
  98.         if (!cbo) {
  99.             clp = lback(clp);
  100.             if (clp == curbp->b_linep) {
  101.                 mlwrite("Not found");
  102.                 scr_co(0x07) ;
  103.                 return (FALSE);
  104.             }
  105.             cbo = llength(clp)+1;
  106.         }
  107.         if (--cbo == llength(clp))
  108.             c = '\n';
  109.         else
  110.             c = lgetc(clp, cbo);
  111.  
  112.         if (eq(c, *epp)) {
  113.             tlp = clp;
  114.             tbo = cbo;
  115.             pp  = epp;
  116.             while (pp != pat) {
  117.                 if (!tbo) {
  118.                     tlp = lback(tlp);
  119.                     if (tlp == curbp->b_linep)
  120.                         goto fail;
  121.                     tbo = llength(tlp)+1;
  122.                 }
  123.                 if (--tbo == llength(tlp))
  124.                     c = '\n';
  125.                 else
  126.                     c = lgetc(tlp, tbo);
  127.                 if (!eq(c, *--pp))
  128.                     goto fail;
  129.             }
  130.             curwp->w_dotp  = tlp;
  131.             curwp->w_doto  = tbo;
  132.             curwp->w_flag |= WFMOVE;
  133.             return (TRUE);
  134.         }
  135.     fail:    ;
  136.     }
  137. }
  138.  
  139. /*
  140.  * Compare two characters: "bc" is the buffer character, "pc" is the
  141.  * pattern character.  If pattern character is upper case, buffer character
  142.  * must also be upper case; else, case is irrelevant.
  143.  */
  144. eq(bc, pc)
  145. register int    bc;
  146. register int    pc;
  147. {
  148.     if ('A'<=pc && pc<='Z') return (bc==pc);
  149.  
  150.     if (bc>='a' && bc<='z')    bc -= 0x20;
  151.     if (pc>='a' && pc<='z')    pc -= 0x20;
  152.     return (bc == pc);
  153. }
  154.  
  155. /*
  156.  * Read a pattern.
  157.  * Stash it in the external
  158.  * variable "pat". The "pat" is
  159.  * not updated if the user types in
  160.  * an empty line. If the user typed
  161.  * an empty line, and there is no
  162.  * old pattern, it is an error.
  163.  * Display the old pattern, in the
  164.  * style of Jeff Lomicka. There is
  165.  * some do-it-yourself control
  166.  * expansion.
  167.  */
  168. readpattern(prompt)
  169. char    *prompt;
  170. {
  171.     register char    *cp1;
  172.     register char    *cp2;
  173.     register int    c;
  174.     register int    s;
  175.     char        tpat[NPAT+20];
  176.  
  177.     cp1 = tpat;                /* Copy prompt        */
  178.     cp2 = prompt;
  179.     while (c = *cp2++)
  180.         *cp1++ = c;
  181.     if (*pat) {            /* Old pattern        */
  182.         *cp1++ = ' ';
  183.         *cp1++ = '[';
  184.         cp2 = pat;
  185.         while (c = *cp2++) {
  186.             if (cp1 < tpat+NPAT+14) {    /* "??]: \0"    */
  187.                 if (c<0x20 || c==0x7F) {
  188.                     *cp1++ = '^';
  189.                     c ^= 0x40;
  190.                 } else if (c == '%')    /* Map "%" to    */
  191.                     *cp1++ = c;    /* "%%".    */
  192.                 *cp1++ = c;
  193.             }
  194.         }
  195.         *cp1++ = ']';
  196.     }
  197.     *cp1++ = ':';                /* Finish prompt    */
  198.     *cp1++ = ' ';
  199.     *cp1++ = '\0';
  200.     s = mlreply(tpat, tpat, NPAT);        /* Read pattern        */
  201.     if (s == TRUE)                /* Specified        */
  202.         strcpy(pat, tpat);
  203.     else if (s==FALSE && *pat)        /* CR, but old one    */
  204.         s = TRUE;
  205.     return (s);
  206. }
  207.  
  208. /*
  209.  * Query and replace.
  210.  * Get a search string from the
  211.  * user, and search, beginning at ".",
  212.  * for the string. If found, reset the
  213.  * "." to be just after the match string,
  214.  * delete N characters backwards where N
  215.  * is the length of the search string,
  216.  * insert the replacement string,
  217.  * and repaint the display.
  218.  */
  219. query_replace(f, n)
  220. {
  221.     register LINE    *clp;
  222.     register int    cbo;
  223.     register LINE    *tlp;
  224.     register int    tbo;
  225.     register int    c;
  226.     register int    s;
  227.     register char    *pp;
  228.     register int    found;
  229.     char s_pat[NPAT];
  230.  
  231.     if ((s=readpattern("Query Replace")) != TRUE)    return (s);
  232.     strcpy(s_pat,pat);
  233.     *pat = '\0';
  234.     if ((s=readpattern("With")) != TRUE) return (s);
  235.  
  236.     found = 0;
  237.     clp = curwp->w_dotp;
  238.     cbo = curwp->w_doto;
  239.     while (clp != curbp->b_linep) {
  240.         if (cbo == llength(clp)) {
  241.             clp = lforw(clp);
  242.             cbo = 0;
  243.             c   = '\n';
  244.         } else c = lgetc(clp, cbo++);
  245.         if (eq(c, *s_pat)) {
  246.             tlp = clp;
  247.             tbo = cbo;
  248.             pp  = s_pat+1;
  249.             while (*pp) {
  250.                 if (tlp == curbp->b_linep) goto done;
  251.                 if (tbo == llength(tlp)) {
  252.                     tlp = lforw(tlp);
  253.                     tbo = 0;
  254.                     c   = '\n';
  255.                 } else c = lgetc(tlp, tbo++);
  256.                 if (!eq(c, *pp++)) goto fail;
  257.             }
  258.             curwp->w_dotp  = tlp;
  259.             curwp->w_doto  = tbo;
  260.             curwp->w_flag |= WFMOVE;
  261.             mlwrite("Replace ? (Y/N):");
  262.             update();
  263.             c = scr_ci() ;
  264.             if (c=='y' || c=='Y' || c==' ') {
  265.                 for (pp=s_pat; *pp; pp++) backdel(FALSE,1);
  266.                 for (pp=pat; *pp; pp++) linsert(1,*pp);
  267.             }
  268.             else if (c==0x07) {
  269.                 scr_co(0x07) ;
  270.                 goto done;
  271.             }
  272.             found = 1;
  273.             if (f && !--n) break;
  274.         }
  275.     fail:    ;
  276.     }
  277.     if (!found) {
  278.         mlwrite("Not found");
  279.         scr_co(0x07) ;
  280.         strcpy(pat,s_pat);
  281.         return (FALSE);
  282.     }
  283. done:
  284.     movecursor(NROW, 0);
  285.     scr_clrl() ;
  286.     strcpy(pat,s_pat);
  287.     return (found);
  288. }
  289.  
  290. /*
  291.  * Search and replace.
  292.  * Get a search string from the
  293.  * user, and search, beginning at ".",
  294.  * for the string. If found, reset the
  295.  * "." to be just after the match string,
  296.  * delete N characters backwards where N
  297.  * is the length of the search string,
  298.  * insert the replacement string,
  299.  * and repaint the display.
  300.  */
  301. search_replace(f, n)
  302. {
  303.     register LINE    *clp;
  304.     register int    cbo;
  305.     register LINE    *tlp;
  306.     register int    tbo;
  307.     register int    c;
  308.     register int    s;
  309.     register char    *pp;
  310.     register int    found;
  311.     char s_pat[NPAT];
  312.  
  313.     if ((s=readpattern("Replace")) != TRUE)    return (s);
  314.     strcpy(s_pat,pat);
  315.     *pat = '\0';
  316.     if ((s=readpattern("With")) != TRUE) return (s);
  317.  
  318.     found = 0;
  319.     clp = curwp->w_dotp;
  320.     cbo = curwp->w_doto;
  321.     while (clp != curbp->b_linep) {
  322.         if (cbo == llength(clp)) {
  323.             clp = lforw(clp);
  324.             cbo = 0;
  325.             c   = '\n';
  326.         } else c = lgetc(clp, cbo++);
  327.         if (eq(c, *s_pat)) {
  328.             tlp = clp;
  329.             tbo = cbo;
  330.             pp  = s_pat+1;
  331.             while (*pp) {
  332.                 if (tlp == curbp->b_linep) goto done;
  333.                 if (tbo == llength(tlp)) {
  334.                     tlp = lforw(tlp);
  335.                     tbo = 0;
  336.                     c   = '\n';
  337.                 } else c = lgetc(tlp, tbo++);
  338.                 if (!eq(c, *pp++)) goto fail;
  339.             }
  340.             curwp->w_dotp  = tlp;
  341.             curwp->w_doto  = tbo;
  342.             curwp->w_flag |= WFMOVE;
  343.             for (pp=s_pat; *pp; pp++) backdel(FALSE,1);
  344.             for (pp=pat; *pp; pp++) linsert(1,*pp);
  345.             found = 1;
  346.             if (f && !--n) break;
  347.         }
  348.     fail:    ;
  349.     }
  350.     if (!found) {
  351.         mlwrite("Not found");
  352.         scr_co(0x07) ;
  353.         strcpy(pat,s_pat);
  354.         return (FALSE);
  355.     }
  356. done:
  357.     movecursor(NROW, 0);
  358.     scr_clrl() ;
  359.     strcpy(pat,s_pat);
  360.     return (found);
  361. }
  362.  
  363.