|
|
1.1 ! root 1: /* move2.c */ ! 2: ! 3: /* Author: ! 4: * Steve Kirkendall ! 5: * 14407 SW Teal Blvd. #C ! 6: * Beaverton, OR 97005 ! 7: * [email protected] ! 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: #ifndef NO_EXTENSIONS ! 23: /*ARGSUSED*/ ! 24: MARK m_wsrch(word, m, cnt) ! 25: char *word; /* the word to search for */ ! 26: MARK m; /* the starting point */ ! 27: int cnt; /* ignored */ ! 28: { ! 29: char buffer[30]; ! 30: ! 31: /* wrap \< and \> around the word */ ! 32: strcpy(buffer, "/\\<"); ! 33: strcat(buffer, word); ! 34: strcat(buffer, "\\>"); ! 35: ! 36: /* show the searched-for word on the bottom line */ ! 37: move(LINES - 1, 0); ! 38: qaddstr(buffer); ! 39: clrtoeol(); ! 40: refresh(); ! 41: ! 42: /* search for the word */ ! 43: return m_fsrch(m, buffer); ! 44: } ! 45: #endif ! 46: ! 47: MARK m_nsrch(m) ! 48: MARK m; /* where to start searching */ ! 49: { ! 50: if (prevsf) ! 51: { ! 52: m = m_fsrch(m, (char *)0); ! 53: prevsf = TRUE; ! 54: } ! 55: else ! 56: { ! 57: m = m_bsrch(m, (char *)0); ! 58: prevsf = FALSE; ! 59: } ! 60: return m; ! 61: } ! 62: ! 63: MARK m_Nsrch(m) ! 64: MARK m; /* where to start searching */ ! 65: { ! 66: if (prevsf) ! 67: { ! 68: m = m_bsrch(m, (char *)0); ! 69: prevsf = TRUE; ! 70: } ! 71: else ! 72: { ! 73: m = m_fsrch(m, (char *)0); ! 74: prevsf = FALSE; ! 75: } ! 76: return m; ! 77: } ! 78: ! 79: MARK m_fsrch(m, ptrn) ! 80: MARK m; /* where to start searching */ ! 81: char *ptrn; /* pattern to search for */ ! 82: { ! 83: long l; /* line# of line to be searched */ ! 84: char *line; /* text of line to be searched */ ! 85: int wrapped;/* boolean: has our search wrapped yet? */ ! 86: int pos; /* where we are in the line */ ! 87: #ifndef CRUNCH ! 88: long delta = INFINITY;/* line offset, for things like "/foo/+1" */ ! 89: #endif ! 90: ! 91: /* remember: "previous search was forward" */ ! 92: prevsf = TRUE; ! 93: ! 94: if (ptrn && *ptrn) ! 95: { ! 96: /* locate the closing '/', if any */ ! 97: line = parseptrn(ptrn); ! 98: #ifndef CRUNCH ! 99: if (*line) ! 100: { ! 101: delta = atol(line); ! 102: } ! 103: #endif ! 104: ptrn++; ! 105: ! 106: /* free the previous pattern */ ! 107: if (re) _free_(re); ! 108: ! 109: /* compile the pattern */ ! 110: re = regcomp(ptrn); ! 111: if (!re) ! 112: { ! 113: return MARK_UNSET; ! 114: } ! 115: } ! 116: else if (!re) ! 117: { ! 118: msg("No previous expression"); ! 119: return MARK_UNSET; ! 120: } ! 121: ! 122: /* search forward for the pattern */ ! 123: pos = markidx(m) + 1; ! 124: pfetch(markline(m)); ! 125: if (pos >= plen) ! 126: { ! 127: pos = 0; ! 128: m = (m | (BLKSIZE - 1)) + 1; ! 129: } ! 130: wrapped = FALSE; ! 131: for (l = markline(m); l != markline(m) + 1 || !wrapped; l++) ! 132: { ! 133: /* wrap search */ ! 134: if (l > nlines) ! 135: { ! 136: /* if we wrapped once already, then the search failed */ ! 137: if (wrapped) ! 138: { ! 139: break; ! 140: } ! 141: ! 142: /* else maybe we should wrap now? */ ! 143: if (*o_wrapscan) ! 144: { ! 145: l = 0; ! 146: wrapped = TRUE; ! 147: continue; ! 148: } ! 149: else ! 150: { ! 151: break; ! 152: } ! 153: } ! 154: ! 155: /* get this line */ ! 156: line = fetchline(l); ! 157: ! 158: /* check this line */ ! 159: if (regexec(re, &line[pos], (pos == 0))) ! 160: { ! 161: /* match! */ ! 162: if (wrapped && *o_warn) ! 163: msg("(wrapped)"); ! 164: #ifndef CRUNCH ! 165: if (delta != INFINITY) ! 166: { ! 167: l += delta; ! 168: if (l < 1 || l > nlines) ! 169: { ! 170: msg("search offset too big"); ! 171: return MARK_UNSET; ! 172: } ! 173: force_flags = LNMD|INCL; ! 174: return MARK_AT_LINE(l); ! 175: } ! 176: #endif ! 177: return MARK_AT_LINE(l) + (int)(re->startp[0] - line); ! 178: } ! 179: pos = 0; ! 180: } ! 181: ! 182: /* not found */ ! 183: msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE"); ! 184: return MARK_UNSET; ! 185: } ! 186: ! 187: MARK m_bsrch(m, ptrn) ! 188: MARK m; /* where to start searching */ ! 189: char *ptrn; /* pattern to search for */ ! 190: { ! 191: long l; /* line# of line to be searched */ ! 192: char *line; /* text of line to be searched */ ! 193: int wrapped;/* boolean: has our search wrapped yet? */ ! 194: int pos; /* last acceptable idx for a match on this line */ ! 195: int last; /* remembered idx of the last acceptable match on this line */ ! 196: int try; /* an idx at which we strat searching for another match */ ! 197: #ifndef CRUNCH ! 198: long delta = INFINITY;/* line offset, for things like "/foo/+1" */ ! 199: #endif ! 200: ! 201: /* remember: "previous search was not forward" */ ! 202: prevsf = FALSE; ! 203: ! 204: if (ptrn && *ptrn) ! 205: { ! 206: /* locate the closing '?', if any */ ! 207: line = parseptrn(ptrn); ! 208: #ifndef CRUNCH ! 209: if (*line) ! 210: { ! 211: delta = atol(line); ! 212: } ! 213: #endif ! 214: ptrn++; ! 215: ! 216: /* free the previous pattern, if any */ ! 217: if (re) _free_(re); ! 218: ! 219: /* compile the pattern */ ! 220: re = regcomp(ptrn); ! 221: if (!re) ! 222: { ! 223: return MARK_UNSET; ! 224: } ! 225: } ! 226: else if (!re) ! 227: { ! 228: msg("No previous expression"); ! 229: return MARK_UNSET; ! 230: } ! 231: ! 232: /* search backward for the pattern */ ! 233: pos = markidx(m); ! 234: wrapped = FALSE; ! 235: for (l = markline(m); l != markline(m) - 1 || !wrapped; l--) ! 236: { ! 237: /* wrap search */ ! 238: if (l < 1) ! 239: { ! 240: if (*o_wrapscan) ! 241: { ! 242: l = nlines + 1; ! 243: wrapped = TRUE; ! 244: continue; ! 245: } ! 246: else ! 247: { ! 248: break; ! 249: } ! 250: } ! 251: ! 252: /* get this line */ ! 253: line = fetchline(l); ! 254: ! 255: /* check this line */ ! 256: if (regexec(re, line, 1) && (int)(re->startp[0] - line) < pos) ! 257: { ! 258: /* match! now find the last acceptable one in this line */ ! 259: do ! 260: { ! 261: last = (int)(re->startp[0] - line); ! 262: try = (int)(re->endp[0] - line); ! 263: } while (try > 0 ! 264: && regexec(re, &line[try], FALSE) ! 265: && (int)(re->startp[0] - line) < pos); ! 266: ! 267: if (wrapped && *o_warn) ! 268: msg("(wrapped)"); ! 269: #ifndef CRUNCH ! 270: if (delta != INFINITY) ! 271: { ! 272: l += delta; ! 273: if (l < 1 || l > nlines) ! 274: { ! 275: msg("search offset too big"); ! 276: return MARK_UNSET; ! 277: } ! 278: force_flags = LNMD|INCL; ! 279: return MARK_AT_LINE(l); ! 280: } ! 281: #endif ! 282: return MARK_AT_LINE(l) + last; ! 283: } ! 284: pos = BLKSIZE; ! 285: } ! 286: ! 287: /* not found */ ! 288: msg(*o_wrapscan ? "Not found" : "Hit top without finding RE"); ! 289: return MARK_UNSET; ! 290: } ! 291:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.