|
|
1.1 ! root 1: /* move2.c */ ! 2: ! 3: /* Author: ! 4: * Steve Kirkendall ! 5: * 16820 SW Tallac Way ! 6: * Beaverton, OR 97006 ! 7: * [email protected], or ...uunet!tektronix!psueea!jove!kirkenda ! 8: */ ! 9: ! 10: ! 11: /* This function contains the movement functions that perform RE searching */ ! 12: ! 13: #include "config.h" ! 14: #include "vi.h" ! 15: #include "regexp.h" ! 16: ! 17: extern long atol(); ! 18: ! 19: static regexp *re; /* compiled version of the pattern to search for */ ! 20: static prevsf; /* boolean: previous search direction was forward? */ ! 21: ! 22: MARK m_nsrch(m) ! 23: MARK m; /* where to start searching */ ! 24: { ! 25: if (prevsf) ! 26: { ! 27: m = m_fsrch(m, (char *)0); ! 28: prevsf = TRUE; ! 29: } ! 30: else ! 31: { ! 32: m = m_bsrch(m, (char *)0); ! 33: prevsf = FALSE; ! 34: } ! 35: return m; ! 36: } ! 37: ! 38: MARK m_Nsrch(m) ! 39: MARK m; /* where to start searching */ ! 40: { ! 41: if (prevsf) ! 42: { ! 43: m = m_bsrch(m, (char *)0); ! 44: prevsf = TRUE; ! 45: } ! 46: else ! 47: { ! 48: m = m_fsrch(m, (char *)0); ! 49: prevsf = FALSE; ! 50: } ! 51: return m; ! 52: } ! 53: ! 54: MARK m_fsrch(m, ptrn) ! 55: MARK m; /* where to start searching */ ! 56: char *ptrn; /* pattern to search for */ ! 57: { ! 58: long l; /* line# of line to be searched */ ! 59: char *line; /* text of line to be searched */ ! 60: int wrapped;/* boolean: has our search wrapped yet? */ ! 61: int pos; /* where we are in the line */ ! 62: long delta; /* line offset, for things like "/foo/+1" */ ! 63: ! 64: /* remember: "previous search was forward" */ ! 65: prevsf = TRUE; ! 66: ! 67: delta = 0L; ! 68: if (ptrn && *ptrn) ! 69: { ! 70: /* locate the closing '/', if any */ ! 71: line = parseptrn(ptrn); ! 72: if (*line) ! 73: { ! 74: delta = atol(line); ! 75: } ! 76: ptrn++; ! 77: ! 78: /* free the previous pattern */ ! 79: if (re) free(re); ! 80: ! 81: /* compile the pattern */ ! 82: re = regcomp(ptrn); ! 83: if (!re) ! 84: { ! 85: return MARK_UNSET; ! 86: } ! 87: } ! 88: else if (!re) ! 89: { ! 90: msg("No previous expression"); ! 91: return MARK_UNSET; ! 92: } ! 93: ! 94: /* search forward for the pattern */ ! 95: pos = markidx(m) + 1; ! 96: pfetch(markline(m)); ! 97: if (pos >= plen) ! 98: { ! 99: pos = 0; ! 100: m = (m | (BLKSIZE - 1)) + 1; ! 101: } ! 102: wrapped = FALSE; ! 103: for (l = markline(m); l != markline(m) + 1 || !wrapped; l++) ! 104: { ! 105: /* wrap search */ ! 106: if (l > nlines) ! 107: { ! 108: /* if we wrapped once already, then the search failed */ ! 109: if (wrapped) ! 110: { ! 111: break; ! 112: } ! 113: ! 114: /* else maybe we should wrap now? */ ! 115: if (*o_wrapscan) ! 116: { ! 117: l = 0; ! 118: wrapped = TRUE; ! 119: continue; ! 120: } ! 121: else ! 122: { ! 123: break; ! 124: } ! 125: } ! 126: ! 127: /* get this line */ ! 128: line = fetchline(l); ! 129: ! 130: /* check this line */ ! 131: if (regexec(re, &line[pos], (pos == 0))) ! 132: { ! 133: /* match! */ ! 134: if (wrapped && *o_warn) ! 135: msg("(wrapped)"); ! 136: if (delta != 0L) ! 137: { ! 138: l += delta; ! 139: if (l < 1 || l > nlines) ! 140: { ! 141: msg("search offset too big"); ! 142: return MARK_UNSET; ! 143: } ! 144: return m_front(MARK_AT_LINE(l), 0L); ! 145: } ! 146: return MARK_AT_LINE(l) + (int)(re->startp[0] - line); ! 147: } ! 148: pos = 0; ! 149: } ! 150: ! 151: /* not found */ ! 152: msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE"); ! 153: return MARK_UNSET; ! 154: } ! 155: ! 156: MARK m_bsrch(m, ptrn) ! 157: MARK m; /* where to start searching */ ! 158: char *ptrn; /* pattern to search for */ ! 159: { ! 160: long l; /* line# of line to be searched */ ! 161: char *line; /* text of line to be searched */ ! 162: int wrapped;/* boolean: has our search wrapped yet? */ ! 163: int pos; /* last acceptable idx for a match on this line */ ! 164: int last; /* remembered idx of the last acceptable match on this line */ ! 165: int try; /* an idx at which we strat searching for another match */ ! 166: ! 167: /* remember: "previous search was not forward" */ ! 168: prevsf = FALSE; ! 169: ! 170: if (ptrn && *ptrn) ! 171: { ! 172: /* locate the closing '?', if any */ ! 173: line = parseptrn(ptrn); ! 174: ptrn++; ! 175: ! 176: /* free the previous pattern, if any */ ! 177: if (re) free(re); ! 178: ! 179: /* compile the pattern */ ! 180: re = regcomp(ptrn); ! 181: if (!re) ! 182: { ! 183: return MARK_UNSET; ! 184: } ! 185: } ! 186: else if (!re) ! 187: { ! 188: msg("No previous expression"); ! 189: return MARK_UNSET; ! 190: } ! 191: ! 192: /* search backward for the pattern */ ! 193: pos = markidx(m); ! 194: wrapped = FALSE; ! 195: for (l = markline(m); l != markline(m) - 1 || !wrapped; l--) ! 196: { ! 197: /* wrap search */ ! 198: if (l < 1) ! 199: { ! 200: if (*o_wrapscan) ! 201: { ! 202: l = nlines + 1; ! 203: wrapped = TRUE; ! 204: continue; ! 205: } ! 206: else ! 207: { ! 208: break; ! 209: } ! 210: } ! 211: ! 212: /* get this line */ ! 213: line = fetchline(l); ! 214: ! 215: /* check this line */ ! 216: if (regexec(re, line, 1) && (int)(re->startp[0] - line) < pos) ! 217: { ! 218: /* match! now find the last acceptable one in this line */ ! 219: do ! 220: { ! 221: last = (int)(re->startp[0] - line); ! 222: try = (int)(re->endp[0] - line); ! 223: } while (try > 0 ! 224: && regexec(re, &line[try], FALSE) ! 225: && (int)(re->startp[0] - line) < pos); ! 226: ! 227: if (wrapped && *o_warn) ! 228: msg("(wrapped)"); ! 229: return MARK_AT_LINE(l) + last; ! 230: } ! 231: pos = BLKSIZE; ! 232: } ! 233: ! 234: /* not found */ ! 235: msg(*o_wrapscan ? "Not found" : "Hit top without finding RE"); ! 236: return MARK_UNSET; ! 237: } ! 238:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.