#include #include #include #include "buf.h" #define REG_ERR_SIZE 100 regex_t re; int re_valid; int forward; char regerr[REG_ERR_SIZE]; static int do_search(struct cmd *c, struct buf *b, int _forward) { struct line *l; regmatch_t match; int err, loop, x, y; l = curr_line; y = cur.y; x = cur.x + 1; if (x > l->len) x = l->len; loop = 0; while (1) { match.rm_so = x; match.rm_eo = l->len; err = regexec(&re, l->line, 1, &match, REG_STARTEND); if (err == 0) { c->new_pos.x = match.rm_so; c->new_pos.y = y; return (0); } else if (err == REG_NOMATCH) { if (_forward) { l = line_next(l); y++; } else { l = line_prev(l); y--; } x = 0; if (l == NULL) { if (loop) { printerr("Pattern not found"); return (1); } printerr("Search wrapped"); loop++; if (_forward) y = 0; else y = b->num_lines - 1; l = buf_get_line(b, y); } continue; } else { regerror(err, &re, regerr, REG_ERR_SIZE); printerr("regexec: %s", regerr); return (1); } } } int cmd_search_next(struct cmd *c, struct buf *b) { int _f; if (re_valid == 0) { printerr("No previous search pattern"); return (1); } _f = forward; if (c->key == 'N') _f = !forward; return (do_search(c, b, _f)); } int cmd_search(struct cmd *c, struct buf *b) { int err, k; if (c->key == '?') forward = 0; else forward = 1; minipos = 0; mvaddch(maxy - 1, 0, c->key); while (1) { k = getch(); if (k == ESC) { minipos = 0; clear_mini(); return (1); } else if (k == BKSPC) { minipos--; if (minipos < 0) minipos = 0; move(maxy - 1, minipos + 1); continue; } else if (k == 13) { if (re_valid) regfree(&re); minib[minipos] = '\0'; if ((err = regcomp(&re, minib, REG_EXTENDED)) != 0) { re_valid = 0; regerror(err, &re, regerr, REG_ERR_SIZE); printerr("Bad pattern: %s", regerr); return (1); } re_valid = 1; return (do_search(c, b, forward)); } minib[minipos++] = k; /* XXX bounds check */ mvaddch(maxy - 1, minipos, k); } }