move2.c

Go to the documentation of this file.
00001 /* move2.c */
00002 
00003 /* Author:
00004  *      Steve Kirkendall
00005  *      14407 SW Teal Blvd. #C
00006  *      Beaverton, OR 97005
00007  *      kirkenda@cs.pdx.edu
00008  */
00009 
00010 
00011 /* This function contains the movement functions that perform RE searching */
00012 
00013 #include "config.h"
00014 #include "vi.h"
00015 #include "regexp.h"
00016 
00017 extern long     atol();
00018 
00019 static regexp   *re;    /* compiled version of the pattern to search for */
00020 static          prevsf; /* boolean: previous search direction was forward? */
00021 
00022 #ifndef NO_EXTENSIONS
00023 /*ARGSUSED*/
00024 MARK m_wsrch(word, m, cnt)
00025         char    *word;  /* the word to search for */
00026         MARK    m;      /* the starting point */
00027         int     cnt;    /* ignored */
00028 {
00029         char    buffer[30];
00030 
00031         /* wrap < and > around the word */
00032         strcpy(buffer, "/\\<");
00033         strcat(buffer, word);
00034         strcat(buffer, "\\>");
00035 
00036         /* show the searched-for word on the bottom line */
00037         move(LINES - 1, 0);
00038         qaddstr(buffer);
00039         clrtoeol();
00040         refresh();
00041 
00042         /* search for the word */
00043         return m_fsrch(m, buffer);
00044 }
00045 #endif
00046 
00047 MARK    m_nsrch(m)
00048         MARK    m;      /* where to start searching */
00049 {
00050         if (prevsf)
00051         {
00052                 m = m_fsrch(m, (char *)0);
00053                 prevsf = TRUE;
00054         }
00055         else
00056         {
00057                 m = m_bsrch(m, (char *)0);
00058                 prevsf = FALSE;
00059         }
00060         return m;
00061 }
00062 
00063 MARK    m_Nsrch(m)
00064         MARK    m;      /* where to start searching */
00065 {
00066         if (prevsf)
00067         {
00068                 m = m_bsrch(m, (char *)0);
00069                 prevsf = TRUE;
00070         }
00071         else
00072         {
00073                 m = m_fsrch(m, (char *)0);
00074                 prevsf = FALSE;
00075         }
00076         return m;
00077 }
00078 
00079 MARK    m_fsrch(m, ptrn)
00080         MARK    m;      /* where to start searching */
00081         char    *ptrn;  /* pattern to search for */
00082 {
00083         long    l;      /* line# of line to be searched */
00084         char    *line;  /* text of line to be searched */
00085         int     wrapped;/* boolean: has our search wrapped yet? */
00086         int     pos;    /* where we are in the line */
00087 #ifndef CRUNCH
00088         long    delta = INFINITY;/* line offset, for things like "/foo/+1" */
00089 #endif
00090 
00091         /* remember: "previous search was forward" */
00092         prevsf = TRUE;
00093 
00094         if (ptrn && *ptrn)
00095         {
00096                 /* locate the closing '/', if any */
00097                 line = parseptrn(ptrn);
00098 #ifndef CRUNCH
00099                 if (*line)
00100                 {
00101                         delta = atol(line);
00102                 }
00103 #endif
00104                 ptrn++;
00105 
00106                 /* free the previous pattern */
00107                 if (re) free(re);
00108 
00109                 /* compile the pattern */
00110                 re = regcomp(ptrn);
00111                 if (!re)
00112                 {
00113                         return MARK_UNSET;
00114                 }
00115         }
00116         else if (!re)
00117         {
00118                 msg("No previous expression");
00119                 return MARK_UNSET;
00120         }
00121 
00122         /* search forward for the pattern */
00123         pos = markidx(m) + 1;
00124         pfetch(markline(m));
00125         if (pos >= plen)
00126         {
00127                 pos = 0;
00128                 m = (m | (BLKSIZE - 1)) + 1;
00129         }
00130         wrapped = FALSE;
00131         for (l = markline(m); l != markline(m) + 1 || !wrapped; l++)
00132         {
00133                 /* wrap search */
00134                 if (l > nlines)
00135                 {
00136                         /* if we wrapped once already, then the search failed */
00137                         if (wrapped)
00138                         {
00139                                 break;
00140                         }
00141 
00142                         /* else maybe we should wrap now? */
00143                         if (*o_wrapscan)
00144                         {
00145                                 l = 0;
00146                                 wrapped = TRUE;
00147                                 continue;
00148                         }
00149                         else
00150                         {
00151                                 break;
00152                         }
00153                 }
00154 
00155                 /* get this line */
00156                 line = fetchline(l);
00157 
00158                 /* check this line */
00159                 if (regexec(re, &line[pos], (pos == 0)))
00160                 {
00161                         /* match! */
00162                         if (wrapped && *o_warn)
00163                                 msg("(wrapped)");
00164 #ifndef CRUNCH
00165                         if (delta != INFINITY)
00166                         {
00167                                 l += delta;
00168                                 if (l < 1 || l > nlines)
00169                                 {
00170                                         msg("search offset too big");
00171                                         return MARK_UNSET;
00172                                 }
00173                                 force_flags = LNMD|INCL;
00174                                 return MARK_AT_LINE(l);
00175                         }
00176 #endif
00177                         return MARK_AT_LINE(l) + (int)(re->startp[0] - line);
00178                 }
00179                 pos = 0;
00180         }
00181 
00182         /* not found */
00183         msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE");
00184         return MARK_UNSET;
00185 }
00186 
00187 MARK    m_bsrch(m, ptrn)
00188         MARK    m;      /* where to start searching */
00189         char    *ptrn;  /* pattern to search for */
00190 {
00191         long    l;      /* line# of line to be searched */
00192         char    *line;  /* text of line to be searched */
00193         int     wrapped;/* boolean: has our search wrapped yet? */
00194         int     pos;    /* last acceptable idx for a match on this line */
00195         int     last;   /* remembered idx of the last acceptable match on this line */
00196         int     try;    /* an idx at which we strat searching for another match */
00197 #ifndef CRUNCH
00198         long    delta = INFINITY;/* line offset, for things like "/foo/+1" */
00199 #endif
00200 
00201         /* remember: "previous search was not forward" */
00202         prevsf = FALSE;
00203 
00204         if (ptrn && *ptrn)
00205         {
00206                 /* locate the closing '?', if any */
00207                 line = parseptrn(ptrn);
00208 #ifndef CRUNCH
00209                 if (*line)
00210                 {
00211                         delta = atol(line);
00212                 }
00213 #endif
00214                 ptrn++;
00215 
00216                 /* free the previous pattern, if any */
00217                 if (re) free(re);
00218 
00219                 /* compile the pattern */
00220                 re = regcomp(ptrn);
00221                 if (!re)
00222                 {
00223                         return MARK_UNSET;
00224                 }
00225         }
00226         else if (!re)
00227         {
00228                 msg("No previous expression");
00229                 return MARK_UNSET;
00230         }
00231 
00232         /* search backward for the pattern */
00233         pos = markidx(m);
00234         wrapped = FALSE;
00235         for (l = markline(m); l != markline(m) - 1 || !wrapped; l--)
00236         {
00237                 /* wrap search */
00238                 if (l < 1)
00239                 {
00240                         if (*o_wrapscan)
00241                         {
00242                                 l = nlines + 1;
00243                                 wrapped = TRUE;
00244                                 continue;
00245                         }
00246                         else
00247                         {
00248                                 break;
00249                         }
00250                 }
00251 
00252                 /* get this line */
00253                 line = fetchline(l);
00254 
00255                 /* check this line */
00256                 if (regexec(re, line, 1) && (int)(re->startp[0] - line) < pos)
00257                 {
00258                         /* match!  now find the last acceptable one in this line */
00259                         do
00260                         {
00261                                 last = (int)(re->startp[0] - line);
00262                                 try = (int)(re->endp[0] - line);
00263                         } while (try > 0
00264                                  && regexec(re, &line[try], FALSE)
00265                                  && (int)(re->startp[0] - line) < pos);
00266 
00267                         if (wrapped && *o_warn)
00268                                 msg("(wrapped)");
00269 #ifndef CRUNCH
00270                         if (delta != INFINITY)
00271                         {
00272                                 l += delta;
00273                                 if (l < 1 || l > nlines)
00274                                 {
00275                                         msg("search offset too big");
00276                                         return MARK_UNSET;
00277                                 }
00278                                 force_flags = LNMD|INCL;
00279                                 return MARK_AT_LINE(l);
00280                         }
00281 #endif
00282                         return MARK_AT_LINE(l) + last;
00283                 }
00284                 pos = BLKSIZE;
00285         }
00286 
00287         /* not found */
00288         msg(*o_wrapscan ? "Not found" : "Hit top without finding RE");
00289         return MARK_UNSET;
00290 }
00291 

Generated on Fri Apr 14 22:56:53 2006 for minix by  doxygen 1.4.6