Reverse Search by Ken Tyler
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@685 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
a75bc41faf
commit
e4933a393a
|
@ -35,6 +35,11 @@ Cvs code -
|
||||||
insert and write routines can't share shortcut lists anymore),
|
insert and write routines can't share shortcut lists anymore),
|
||||||
new args to do_writeout and write_file called append, and of source
|
new args to do_writeout and write_file called append, and of source
|
||||||
code changes to those functions.
|
code changes to those functions.
|
||||||
|
- Allow backwards searching. Drastic rewrite of the search prompt
|
||||||
|
string by Chris. All other code by Ken Tyler. New globals
|
||||||
|
nano_reverse_msg, new functions revstrstr and revstrcasestr,
|
||||||
|
many changes to search functions. Not too big a code size
|
||||||
|
increase!
|
||||||
- configure.in:
|
- configure.in:
|
||||||
- New option, --enable-nanorc, which allows people to have a .nanorc
|
- New option, --enable-nanorc, which allows people to have a .nanorc
|
||||||
initialization file and set options normally used on the command
|
initialization file and set options normally used on the command
|
||||||
|
|
15
global.c
15
global.c
|
@ -194,7 +194,7 @@ void shortcut_init(int unjustify)
|
||||||
"", *nano_backspace_msg = "", *nano_tab_msg =
|
"", *nano_backspace_msg = "", *nano_tab_msg =
|
||||||
"", *nano_enter_msg = "", *nano_case_msg =
|
"", *nano_enter_msg = "", *nano_case_msg =
|
||||||
"", *nano_cancel_msg = "", *nano_unjustify_msg =
|
"", *nano_cancel_msg = "", *nano_unjustify_msg =
|
||||||
"", *nano_append_msg = "";
|
"", *nano_append_msg = "", *nano_reverse_msg = "";
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
char *nano_tofiles_msg = "";
|
char *nano_tofiles_msg = "";
|
||||||
|
@ -236,6 +236,7 @@ void shortcut_init(int unjustify)
|
||||||
nano_gotodir_msg = _("Goto Directory");
|
nano_gotodir_msg = _("Goto Directory");
|
||||||
nano_cancel_msg = _("Cancel the current function");
|
nano_cancel_msg = _("Cancel the current function");
|
||||||
nano_append_msg = _("Append to the current file");
|
nano_append_msg = _("Append to the current file");
|
||||||
|
nano_reverse_msg = _("Search Backwards");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sc_init_one(&main_list[0], NANO_HELP_KEY, _("Get Help"),
|
sc_init_one(&main_list[0], NANO_HELP_KEY, _("Get Help"),
|
||||||
|
@ -369,9 +370,11 @@ void shortcut_init(int unjustify)
|
||||||
_("Goto Line"), nano_goto_msg, 0, 0, 0, VIEW,
|
_("Goto Line"), nano_goto_msg, 0, 0, 0, VIEW,
|
||||||
do_gotoline_void);
|
do_gotoline_void);
|
||||||
|
|
||||||
sc_init_one(&whereis_list[5], NANO_CANCEL_KEY, _("Cancel"),
|
sc_init_one(&whereis_list[5], NANO_REVERSESEARCH_KEY, _("Backward"),
|
||||||
nano_cancel_msg, 0, 0, 0, VIEW, 0);
|
nano_reverse_msg, 0, 0, 0, VIEW, 0);
|
||||||
|
|
||||||
|
sc_init_one(&whereis_list[6], NANO_CANCEL_KEY, _("Cancel"),
|
||||||
|
nano_cancel_msg, 0, 0, 0, VIEW, 0);
|
||||||
|
|
||||||
sc_init_one(&replace_list[0], NANO_FIRSTLINE_KEY, _("First Line"),
|
sc_init_one(&replace_list[0], NANO_FIRSTLINE_KEY, _("First Line"),
|
||||||
nano_firstline_msg, 0, 0, 0, VIEW, do_first_line);
|
nano_firstline_msg, 0, 0, 0, VIEW, do_first_line);
|
||||||
|
@ -389,9 +392,11 @@ void shortcut_init(int unjustify)
|
||||||
_("Goto Line"), nano_goto_msg, 0, 0, 0, VIEW,
|
_("Goto Line"), nano_goto_msg, 0, 0, 0, VIEW,
|
||||||
do_gotoline_void);
|
do_gotoline_void);
|
||||||
|
|
||||||
sc_init_one(&replace_list[5], NANO_CANCEL_KEY, _("Cancel"),
|
sc_init_one(&replace_list[5], NANO_REVERSESEARCH_KEY, _("Backward"),
|
||||||
nano_cancel_msg, 0, 0, 0, VIEW, 0);
|
nano_reverse_msg, 0, 0, 0, VIEW, 0);
|
||||||
|
|
||||||
|
sc_init_one(&replace_list[6], NANO_CANCEL_KEY, _("Cancel"),
|
||||||
|
nano_cancel_msg, 0, 0, 0, VIEW, 0);
|
||||||
|
|
||||||
|
|
||||||
sc_init_one(&replace_list_2[0], NANO_FIRSTLINE_KEY, _("First Line"),
|
sc_init_one(&replace_list_2[0], NANO_FIRSTLINE_KEY, _("First Line"),
|
||||||
|
|
6
nano.h
6
nano.h
|
@ -123,6 +123,7 @@ typedef struct rcoption {
|
||||||
#define TEMP_OPT (1<<16)
|
#define TEMP_OPT (1<<16)
|
||||||
#define CUT_TO_END (1<<17)
|
#define CUT_TO_END (1<<17)
|
||||||
#define DISABLE_CURPOS (1<<18)
|
#define DISABLE_CURPOS (1<<18)
|
||||||
|
#define REVERSE_SEARCH (1<<19)
|
||||||
|
|
||||||
/* Control key sequences, changing these would be very very bad */
|
/* Control key sequences, changing these would be very very bad */
|
||||||
|
|
||||||
|
@ -205,6 +206,7 @@ know what you're doing */
|
||||||
#define NANO_REPLACE_FKEY KEY_F(14)
|
#define NANO_REPLACE_FKEY KEY_F(14)
|
||||||
#define NANO_ALT_REPLACE_KEY NANO_ALT_R
|
#define NANO_ALT_REPLACE_KEY NANO_ALT_R
|
||||||
#define NANO_OTHERSEARCH_KEY NANO_CONTROL_R
|
#define NANO_OTHERSEARCH_KEY NANO_CONTROL_R
|
||||||
|
#define NANO_REVERSESEARCH_KEY NANO_CONTROL_B
|
||||||
#define NANO_PREVPAGE_KEY NANO_CONTROL_Y
|
#define NANO_PREVPAGE_KEY NANO_CONTROL_Y
|
||||||
#define NANO_PREVPAGE_FKEY KEY_F(7)
|
#define NANO_PREVPAGE_FKEY KEY_F(7)
|
||||||
#define NANO_NEXTPAGE_KEY NANO_CONTROL_V
|
#define NANO_NEXTPAGE_KEY NANO_CONTROL_V
|
||||||
|
@ -253,8 +255,8 @@ know what you're doing */
|
||||||
|
|
||||||
#define MAIN_LIST_LEN 26
|
#define MAIN_LIST_LEN 26
|
||||||
#define MAIN_VISIBLE 12
|
#define MAIN_VISIBLE 12
|
||||||
#define WHEREIS_LIST_LEN 6
|
#define WHEREIS_LIST_LEN 7
|
||||||
#define REPLACE_LIST_LEN 6
|
#define REPLACE_LIST_LEN 7
|
||||||
#define REPLACE_LIST_2_LEN 3
|
#define REPLACE_LIST_2_LEN 3
|
||||||
#define GOTO_LIST_LEN 3
|
#define GOTO_LIST_LEN 3
|
||||||
#define GOTODIR_LIST_LEN 1
|
#define GOTODIR_LIST_LEN 1
|
||||||
|
|
4
proto.h
4
proto.h
|
@ -71,8 +71,10 @@ extern toggle toggles[TOGGLE_LEN];
|
||||||
|
|
||||||
/* Programs we want available */
|
/* Programs we want available */
|
||||||
|
|
||||||
|
char *revstrstr(char *haystack, char *needle, char *rev_start);
|
||||||
char *strcasestr(char *haystack, char *needle);
|
char *strcasestr(char *haystack, char *needle);
|
||||||
char *strstrwrapper(char *haystack, char *needle);
|
char *revstrcasestr(char *haystack, char *needle, char *rev_start);
|
||||||
|
char *strstrwrapper(char *haystack, char *needle, char *rev_start);
|
||||||
int search_init(int replacing);
|
int search_init(int replacing);
|
||||||
int renumber(filestruct * fileptr);
|
int renumber(filestruct * fileptr);
|
||||||
int free_filestruct(filestruct * src);
|
int free_filestruct(filestruct * src);
|
||||||
|
|
174
search.c
174
search.c
|
@ -74,7 +74,7 @@ int search_init(int replacing)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char *buf;
|
char *buf;
|
||||||
char *prompt, *reprompt = "";
|
char *prompt;
|
||||||
static char *backupstring = NULL;
|
static char *backupstring = NULL;
|
||||||
|
|
||||||
search_init_globals();
|
search_init_globals();
|
||||||
|
@ -114,22 +114,21 @@ int search_init(int replacing)
|
||||||
else
|
else
|
||||||
strcpy(buf, "");
|
strcpy(buf, "");
|
||||||
|
|
||||||
if (ISSET(USE_REGEXP) && ISSET(CASE_SENSITIVE))
|
/* Instead of having a million if statements here to determine
|
||||||
prompt = _("Case Sensitive Regexp Search%s%s");
|
the prompt, we instead just have a hundred "? :" calls in
|
||||||
else if (ISSET(USE_REGEXP))
|
the statusq call. I hope no one ever has to modify this :-) */
|
||||||
prompt = _("Regexp Search%s%s");
|
prompt = "%s%s%s%s%s%s";
|
||||||
else if (ISSET(CASE_SENSITIVE))
|
|
||||||
prompt = _("Case Sensitive Search%s%s");
|
|
||||||
else
|
|
||||||
prompt = _("Search%s%s");
|
|
||||||
|
|
||||||
if (replacing)
|
|
||||||
reprompt = _(" (to replace)");
|
|
||||||
|
|
||||||
/* This is now one simple call. It just does a lot */
|
/* This is now one simple call. It just does a lot */
|
||||||
i = statusq(0, replacing ? replace_list : whereis_list,
|
i = statusq(0, replacing ? replace_list : whereis_list,
|
||||||
replacing ? REPLACE_LIST_LEN : WHEREIS_LIST_LEN, backupstring,
|
replacing ? REPLACE_LIST_LEN : WHEREIS_LIST_LEN, backupstring,
|
||||||
prompt, reprompt, buf);
|
prompt,
|
||||||
|
ISSET(CASE_SENSITIVE) ? _("Case Sensitive ") : "",
|
||||||
|
ISSET(USE_REGEXP) ? _("Regexp ") : "",
|
||||||
|
_("Search"),
|
||||||
|
ISSET(REVERSE_SEARCH) ? _(" Backwards") : "",
|
||||||
|
replacing ? _(" (to replace)") : "",
|
||||||
|
buf);
|
||||||
|
|
||||||
/* Cancel any search, or just return with no previous search */
|
/* Cancel any search, or just return with no previous search */
|
||||||
if ((i == -1) || (i < 0 && !last_search[0])) {
|
if ((i == -1) || (i < 0 && !last_search[0])) {
|
||||||
|
@ -173,6 +172,17 @@ int search_init(int replacing)
|
||||||
} else if (i == NANO_OTHERSEARCH_KEY) {
|
} else if (i == NANO_OTHERSEARCH_KEY) {
|
||||||
backupstring = mallocstrcpy(backupstring, answer);
|
backupstring = mallocstrcpy(backupstring, answer);
|
||||||
return -2; /* Call the opposite search function */
|
return -2; /* Call the opposite search function */
|
||||||
|
} else if (i == NANO_REVERSESEARCH_KEY) {
|
||||||
|
free(backupstring);
|
||||||
|
backupstring = NULL;
|
||||||
|
backupstring = mallocstrcpy(backupstring, answer);
|
||||||
|
|
||||||
|
if (ISSET(REVERSE_SEARCH))
|
||||||
|
UNSET(REVERSE_SEARCH);
|
||||||
|
else
|
||||||
|
SET(REVERSE_SEARCH);
|
||||||
|
|
||||||
|
return 1;
|
||||||
} else if (i == NANO_FROMSEARCHTOGOTO_KEY) {
|
} else if (i == NANO_FROMSEARCHTOGOTO_KEY) {
|
||||||
free(backupstring);
|
free(backupstring);
|
||||||
backupstring = NULL;
|
backupstring = NULL;
|
||||||
|
@ -207,68 +217,124 @@ filestruct *findnextstr(int quiet, filestruct * begin, int beginx,
|
||||||
char *needle)
|
char *needle)
|
||||||
{
|
{
|
||||||
filestruct *fileptr;
|
filestruct *fileptr;
|
||||||
char *searchstr, *found = NULL, *tmp;
|
char *searchstr, *rev_start = NULL, *found = NULL;
|
||||||
int past_editbot = 0, current_x_find;
|
int past_editbot = 0, current_x_find;
|
||||||
|
|
||||||
fileptr = current;
|
fileptr = current;
|
||||||
|
|
||||||
current_x_find = current_x + 1;
|
if (!ISSET(REVERSE_SEARCH)) { /* forward search */
|
||||||
|
|
||||||
/* Are we searching the last line? (i.e. the line where search started) */
|
current_x_find = current_x + 1;
|
||||||
if ((fileptr == begin) && (current_x_find < beginx))
|
|
||||||
search_last_line = 1;
|
|
||||||
|
|
||||||
/* Make sure we haven't passed the end of the string */
|
/* Are we now back to the line where the search started) */
|
||||||
if (strlen(fileptr->data) < current_x_find)
|
if ((fileptr == begin) && (current_x_find < beginx))
|
||||||
current_x_find--;
|
search_last_line = 1;
|
||||||
|
|
||||||
searchstr = &fileptr->data[current_x_find];
|
/* Make sure we haven't passed the end of the string */
|
||||||
|
if (strlen(fileptr->data) < current_x_find)
|
||||||
|
current_x_find--;
|
||||||
|
|
||||||
/* Look for needle in searchstr */
|
searchstr = &fileptr->data[current_x_find];
|
||||||
while ((found = strstrwrapper(searchstr, needle)) == NULL) {
|
|
||||||
|
|
||||||
/* finished processing file, get out */
|
/* Look for needle in searchstr */
|
||||||
if (search_last_line) {
|
while ((found = strstrwrapper(searchstr, needle, rev_start)) == NULL) {
|
||||||
|
|
||||||
|
/* finished processing file, get out */
|
||||||
|
if (search_last_line) {
|
||||||
|
if (!quiet)
|
||||||
|
not_found_msg(needle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileptr = fileptr->next;
|
||||||
|
|
||||||
|
if (!past_editbot && (fileptr == editbot))
|
||||||
|
past_editbot = 1;
|
||||||
|
|
||||||
|
/* EOF reached ?, wrap around once */
|
||||||
|
if (fileptr == NULL) {
|
||||||
|
fileptr = fileage;
|
||||||
|
past_editbot = 1;
|
||||||
|
if (!quiet)
|
||||||
|
statusbar(_("Search Wrapped"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Original start line reached */
|
||||||
|
if (fileptr == begin)
|
||||||
|
search_last_line = 1;
|
||||||
|
|
||||||
|
searchstr = fileptr->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We found an instance */
|
||||||
|
current_x_find = found - fileptr->data;
|
||||||
|
|
||||||
|
/* Ensure we haven't wrapped around again! */
|
||||||
|
if ((search_last_line) && (current_x_find >= beginx)) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
not_found_msg(needle);
|
not_found_msg(needle);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileptr = fileptr->next;
|
} else { /* reverse search */
|
||||||
|
|
||||||
if (!past_editbot && (fileptr == editbot))
|
current_x_find = current_x - 1;
|
||||||
past_editbot = 1;
|
|
||||||
|
|
||||||
/* EOF reached, wrap around once */
|
/* Are we now back to the line where the search started) */
|
||||||
if (fileptr == NULL) {
|
if ((fileptr == begin) && (current_x_find > beginx))
|
||||||
fileptr = fileage;
|
|
||||||
|
|
||||||
past_editbot = 1;
|
|
||||||
|
|
||||||
if (!quiet)
|
|
||||||
statusbar(_("Search Wrapped"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Original start line reached */
|
|
||||||
if (fileptr == begin)
|
|
||||||
search_last_line = 1;
|
search_last_line = 1;
|
||||||
|
|
||||||
|
/* Make sure we haven't passed the begining of the string */
|
||||||
|
#if 0 /* Is this required here ? */
|
||||||
|
if (!(&fileptr->data[current_x_find] - fileptr->data))
|
||||||
|
current_x_find++;
|
||||||
|
#endif
|
||||||
|
rev_start = &fileptr->data[current_x_find];
|
||||||
searchstr = fileptr->data;
|
searchstr = fileptr->data;
|
||||||
|
|
||||||
|
/* Look for needle in searchstr */
|
||||||
|
while ((found = strstrwrapper(searchstr, needle, rev_start)) == NULL) {
|
||||||
|
|
||||||
|
/* finished processing file, get out */
|
||||||
|
if (search_last_line) {
|
||||||
|
if (!quiet)
|
||||||
|
not_found_msg(needle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileptr = fileptr->prev;
|
||||||
|
|
||||||
|
/* ? */ if (!past_editbot && (fileptr == edittop->prev))
|
||||||
|
past_editbot = 1;
|
||||||
|
|
||||||
|
/* SOF reached ?, wrap around once */
|
||||||
|
/* ? */ if (fileptr == NULL) {
|
||||||
|
fileptr = filebot;
|
||||||
|
past_editbot = 1;
|
||||||
|
if (!quiet)
|
||||||
|
statusbar(_("Search Wrapped"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Original start line reached */
|
||||||
|
if (fileptr == begin)
|
||||||
|
search_last_line = 1;
|
||||||
|
|
||||||
|
searchstr = fileptr->data;
|
||||||
|
rev_start = fileptr->data + strlen(fileptr->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We found an instance */
|
||||||
|
current_x_find = found - fileptr->data;
|
||||||
|
|
||||||
|
/* Ensure we haven't wrapped around again! */
|
||||||
|
if ((search_last_line) && (current_x_find < beginx)) {
|
||||||
|
if (!quiet)
|
||||||
|
not_found_msg(needle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We found an instance */
|
/* Set globals now that we are sure we found something */
|
||||||
current_x_find = 0;
|
|
||||||
for (tmp = fileptr->data; tmp != found; tmp++)
|
|
||||||
current_x_find++;
|
|
||||||
|
|
||||||
/* Ensure we haven't wrapped around again! */
|
|
||||||
if ((search_last_line) && (current_x_find >= beginx)) {
|
|
||||||
if (!quiet)
|
|
||||||
not_found_msg(needle);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set globals, now that we are sure we found something */
|
|
||||||
current = fileptr;
|
current = fileptr;
|
||||||
current_x = current_x_find;
|
current_x = current_x_find;
|
||||||
|
|
||||||
|
|
71
utils.c
71
utils.c
|
@ -47,6 +47,31 @@ void lowercase(char *src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *revstrstr(char *haystack, char *needle, char *rev_start)
|
||||||
|
{
|
||||||
|
char *p, *q, *r;
|
||||||
|
|
||||||
|
for(p = rev_start ; p >= haystack ; --p) {
|
||||||
|
for (r = p, q = needle ; (*q == *r) && (*q != '\0') ; r++, q++)
|
||||||
|
;
|
||||||
|
if (*q == '\0')
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *revstrcasestr(char *haystack, char *needle, char *rev_start)
|
||||||
|
{
|
||||||
|
char *p, *q, *r;
|
||||||
|
|
||||||
|
for(p = rev_start ; p >= haystack ; --p) {
|
||||||
|
for (r = p, q = needle ; (tolower(*q) == tolower(*r)) && (*q != '\0') ; r++, q++)
|
||||||
|
;
|
||||||
|
if (*q == '\0')
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is now mutt's version (called mutt_stristr) because it doesn't
|
/* This is now mutt's version (called mutt_stristr) because it doesn't
|
||||||
use memory allocation to do a simple search (yuck). */
|
use memory allocation to do a simple search (yuck). */
|
||||||
|
@ -59,31 +84,55 @@ char *strcasestr(char *haystack, char *needle)
|
||||||
if (!needle)
|
if (!needle)
|
||||||
return (haystack);
|
return (haystack);
|
||||||
|
|
||||||
while (*(p = haystack))
|
while (*(p = haystack)) {
|
||||||
{
|
|
||||||
for (q = needle; *p && *q && tolower (*p) == tolower (*q); p++, q++)
|
for (q = needle; *p && *q && tolower (*p) == tolower (*q); p++, q++)
|
||||||
;
|
;
|
||||||
if (!*q)
|
if (!*q)
|
||||||
return (haystack);
|
return (haystack);
|
||||||
haystack++;
|
haystack++;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strstrwrapper(char *haystack, char *needle)
|
char *strstrwrapper(char *haystack, char *needle, char *rev_start)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef HAVE_REGEX_H
|
#ifdef HAVE_REGEX_H
|
||||||
|
|
||||||
|
int result;
|
||||||
|
char *i, *j;
|
||||||
|
|
||||||
if (ISSET(USE_REGEXP)) {
|
if (ISSET(USE_REGEXP)) {
|
||||||
int result = regexec(&search_regexp, haystack, 10, regmatches, 0);
|
if (!ISSET(REVERSE_SEARCH)) {
|
||||||
if (!result)
|
result = regexec(&search_regexp, haystack, 10, regmatches, 0);
|
||||||
return haystack + regmatches[0].rm_so;
|
if (!result)
|
||||||
|
return haystack + regmatches[0].rm_so;
|
||||||
|
} else {
|
||||||
|
/* do quick check first */
|
||||||
|
if (!(regexec(&search_regexp, haystack, 10, regmatches, 0))) {
|
||||||
|
/* there is a match */
|
||||||
|
for(i = rev_start ; i >= haystack ; --i)
|
||||||
|
if (!(result = regexec(&search_regexp, i, 10, regmatches, 0))) {
|
||||||
|
j = i + regmatches[0].rm_so;
|
||||||
|
if (j <= rev_start)
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ISSET(CASE_SENSITIVE))
|
if (ISSET(CASE_SENSITIVE)) {
|
||||||
return strstr(haystack, needle);
|
if (!ISSET(REVERSE_SEARCH))
|
||||||
else
|
return strstr(haystack,needle);
|
||||||
return strcasestr(haystack, needle);
|
else
|
||||||
|
return revstrstr(haystack, needle, rev_start);
|
||||||
|
} else {
|
||||||
|
if (!ISSET(REVERSE_SEARCH))
|
||||||
|
return strcasestr(haystack, needle);
|
||||||
|
else
|
||||||
|
return revstrcasestr(haystack, needle, rev_start);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Thanks BG, many ppl have been asking for this... */
|
/* Thanks BG, many ppl have been asking for this... */
|
||||||
|
|
Loading…
Reference in New Issue