#include "histedit.h"Include dependency graph for search.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Classes | |
| struct | el_search_t |
Functions | |
| protected int | el_match (const char *, const char *) |
| protected int | search_init (EditLine *) |
| protected void | search_end (EditLine *) |
| protected int | c_hmatch (EditLine *, const char *) |
| protected void | c_setpat (EditLine *) |
| protected el_action_t | ce_inc_search (EditLine *, int) |
| protected el_action_t | cv_search (EditLine *, int) |
| protected el_action_t | ce_search_line (EditLine *, int) |
| protected el_action_t | cv_repeat_srch (EditLine *, int) |
| protected el_action_t | cv_csearch (EditLine *, int, int, int, int) |
| protected int c_hmatch | ( | EditLine * | , | |
| const char * | ||||
| ) |
Definition at line 148 of file search.c.
References el, editline::el_errfile, el_match(), editline::el_search, and el_search_t::patbuf.
Referenced by ed_search_next_history(), and ed_search_prev_history().
00149 { 00150 #ifdef SDEBUG 00151 (void) fprintf(el->el_errfile, "match `%s' with `%s'\n", 00152 el->el_search.patbuf, str); 00153 #endif /* SDEBUG */ 00154 00155 return (el_match(str, el->el_search.patbuf)); 00156 }
Here is the call graph for this function:

Here is the caller graph for this function:

| protected void c_setpat | ( | EditLine * | ) |
Definition at line 163 of file search.c.
References el_line_t::buffer, el, EL_BUFSIZ, EL_CURSOR, editline::el_errfile, editline::el_history, editline::el_line, editline::el_search, editline::el_state, el_history_t::eventno, el_line_t::lastchar, el_state_t::lastcmd, el_search_t::patbuf, el_search_t::patlen, and strlen().
Referenced by ed_search_next_history(), and ed_search_prev_history().
00164 { 00165 if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY && 00166 el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) { 00167 el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer; 00168 if (el->el_search.patlen >= EL_BUFSIZ) 00169 el->el_search.patlen = EL_BUFSIZ - 1; 00170 if (el->el_search.patlen != 0) { 00171 (void) strncpy(el->el_search.patbuf, el->el_line.buffer, 00172 el->el_search.patlen); 00173 el->el_search.patbuf[el->el_search.patlen] = '\0'; 00174 } else 00175 el->el_search.patlen = strlen(el->el_search.patbuf); 00176 } 00177 #ifdef SDEBUG 00178 (void) fprintf(el->el_errfile, "\neventno = %d\n", 00179 el->el_history.eventno); 00180 (void) fprintf(el->el_errfile, "patlen = %d\n", el->el_search.patlen); 00181 (void) fprintf(el->el_errfile, "patbuf = \"%s\"\n", 00182 el->el_search.patbuf); 00183 (void) fprintf(el->el_errfile, "cursor %d lastchar %d\n", 00184 EL_CURSOR(el) - el->el_line.buffer, 00185 el->el_line.lastchar - el->el_line.buffer); 00186 #endif 00187 }
Here is the call graph for this function:

Here is the caller graph for this function:

| protected el_action_t ce_inc_search | ( | EditLine * | , | |
| int | ||||
| ) |
Definition at line 194 of file search.c.
References ANCHOR, c__next_word(), CC_ERROR, CC_NORM, CC_REFRESH, ce__isword(), el_line_t::cursor, define(), ed_end_of_file(), el, EL_BUFSIZ, el_getc(), editline::el_history, editline::el_line, el_push(), editline::el_search, el_history_t::eventno, isglob, el_line_t::lastchar, LEN, el_line_t::limit, el_search_t::patbuf, el_search_t::patlen, pchar, re_refresh(), and term_beep().
Referenced by em_inc_search_next(), and em_inc_search_prev().
00195 { 00196 static const char STRfwd[] = {'f', 'w', 'd', '\0'}, 00197 STRbck[] = {'b', 'c', 'k', '\0'}; 00198 static char pchar = ':';/* ':' = normal, '?' = failed */ 00199 static char endcmd[2] = {'\0', '\0'}; 00200 char ch, *ocursor = el->el_line.cursor, oldpchar = pchar; 00201 const char *cp; 00202 00203 el_action_t ret = CC_NORM; 00204 00205 int ohisteventno = el->el_history.eventno; 00206 int oldpatlen = el->el_search.patlen; 00207 int newdir = dir; 00208 int done, redo; 00209 00210 if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 + 00211 el->el_search.patlen >= el->el_line.limit) 00212 return (CC_ERROR); 00213 00214 for (;;) { 00215 00216 if (el->el_search.patlen == 0) { /* first round */ 00217 pchar = ':'; 00218 #ifdef ANCHOR 00219 #define LEN 2 00220 el->el_search.patbuf[el->el_search.patlen++] = '.'; 00221 el->el_search.patbuf[el->el_search.patlen++] = '*'; 00222 #else 00223 #define LEN 0 00224 #endif 00225 } 00226 done = redo = 0; 00227 *el->el_line.lastchar++ = '\n'; 00228 for (cp = (newdir == ED_SEARCH_PREV_HISTORY) ? STRbck : STRfwd; 00229 *cp; *el->el_line.lastchar++ = *cp++) 00230 continue; 00231 *el->el_line.lastchar++ = pchar; 00232 for (cp = &el->el_search.patbuf[LEN]; 00233 cp < &el->el_search.patbuf[el->el_search.patlen]; 00234 *el->el_line.lastchar++ = *cp++) 00235 continue; 00236 *el->el_line.lastchar = '\0'; 00237 re_refresh(el); 00238 00239 if (el_getc(el, &ch) != 1) 00240 return (ed_end_of_file(el, 0)); 00241 00242 switch (el->el_map.current[(unsigned char) ch]) { 00243 case ED_INSERT: 00244 case ED_DIGIT: 00245 if (el->el_search.patlen >= EL_BUFSIZ - LEN) 00246 term_beep(el); 00247 else { 00248 el->el_search.patbuf[el->el_search.patlen++] = 00249 ch; 00250 *el->el_line.lastchar++ = ch; 00251 *el->el_line.lastchar = '\0'; 00252 re_refresh(el); 00253 } 00254 break; 00255 00256 case EM_INC_SEARCH_NEXT: 00257 newdir = ED_SEARCH_NEXT_HISTORY; 00258 redo++; 00259 break; 00260 00261 case EM_INC_SEARCH_PREV: 00262 newdir = ED_SEARCH_PREV_HISTORY; 00263 redo++; 00264 break; 00265 00266 case EM_DELETE_PREV_CHAR: 00267 case ED_DELETE_PREV_CHAR: 00268 if (el->el_search.patlen > LEN) 00269 done++; 00270 else 00271 term_beep(el); 00272 break; 00273 00274 default: 00275 switch (ch) { 00276 case 0007: /* ^G: Abort */ 00277 ret = CC_ERROR; 00278 done++; 00279 break; 00280 00281 case 0027: /* ^W: Append word */ 00282 /* No can do if globbing characters in pattern */ 00283 for (cp = &el->el_search.patbuf[LEN];; cp++) 00284 if (cp >= &el->el_search.patbuf[ 00285 el->el_search.patlen]) { 00286 el->el_line.cursor += 00287 el->el_search.patlen - LEN - 1; 00288 cp = c__next_word(el->el_line.cursor, 00289 el->el_line.lastchar, 1, 00290 ce__isword); 00291 while (el->el_line.cursor < cp && 00292 *el->el_line.cursor != '\n') { 00293 if (el->el_search.patlen >= 00294 EL_BUFSIZ - LEN) { 00295 term_beep(el); 00296 break; 00297 } 00298 el->el_search.patbuf[el->el_search.patlen++] = 00299 *el->el_line.cursor; 00300 *el->el_line.lastchar++ = 00301 *el->el_line.cursor++; 00302 } 00303 el->el_line.cursor = ocursor; 00304 *el->el_line.lastchar = '\0'; 00305 re_refresh(el); 00306 break; 00307 } else if (isglob(*cp)) { 00308 term_beep(el); 00309 break; 00310 } 00311 break; 00312 00313 default: /* Terminate and execute cmd */ 00314 endcmd[0] = ch; 00315 el_push(el, endcmd); 00316 /* FALLTHROUGH */ 00317 00318 case 0033: /* ESC: Terminate */ 00319 ret = CC_REFRESH; 00320 done++; 00321 break; 00322 } 00323 break; 00324 } 00325 00326 while (el->el_line.lastchar > el->el_line.buffer && 00327 *el->el_line.lastchar != '\n') 00328 *el->el_line.lastchar-- = '\0'; 00329 *el->el_line.lastchar = '\0'; 00330 00331 if (!done) { 00332 00333 /* Can't search if unmatched '[' */ 00334 for (cp = &el->el_search.patbuf[el->el_search.patlen-1], 00335 ch = ']'; 00336 cp >= &el->el_search.patbuf[LEN]; 00337 cp--) 00338 if (*cp == '[' || *cp == ']') { 00339 ch = *cp; 00340 break; 00341 } 00342 if (el->el_search.patlen > LEN && ch != '[') { 00343 if (redo && newdir == dir) { 00344 if (pchar == '?') { /* wrap around */ 00345 el->el_history.eventno = 00346 newdir == ED_SEARCH_PREV_HISTORY ? 0 : 0x7fffffff; 00347 if (hist_get(el) == CC_ERROR) 00348 /* el->el_history.event 00349 * no was fixed by 00350 * first call */ 00351 (void) hist_get(el); 00352 el->el_line.cursor = newdir == 00353 ED_SEARCH_PREV_HISTORY ? 00354 el->el_line.lastchar : 00355 el->el_line.buffer; 00356 } else 00357 el->el_line.cursor += 00358 newdir == 00359 ED_SEARCH_PREV_HISTORY ? 00360 -1 : 1; 00361 } 00362 #ifdef ANCHOR 00363 el->el_search.patbuf[el->el_search.patlen++] = 00364 '.'; 00365 el->el_search.patbuf[el->el_search.patlen++] = 00366 '*'; 00367 #endif 00368 el->el_search.patbuf[el->el_search.patlen] = 00369 '\0'; 00370 if (el->el_line.cursor < el->el_line.buffer || 00371 el->el_line.cursor > el->el_line.lastchar || 00372 (ret = ce_search_line(el, newdir)) 00373 == CC_ERROR) { 00374 /* avoid c_setpat */ 00375 el->el_state.lastcmd = 00376 (el_action_t) newdir; 00377 ret = newdir == ED_SEARCH_PREV_HISTORY ? 00378 ed_search_prev_history(el, 0) : 00379 ed_search_next_history(el, 0); 00380 if (ret != CC_ERROR) { 00381 el->el_line.cursor = newdir == 00382 ED_SEARCH_PREV_HISTORY ? 00383 el->el_line.lastchar : 00384 el->el_line.buffer; 00385 (void) ce_search_line(el, 00386 newdir); 00387 } 00388 } 00389 el->el_search.patlen -= LEN; 00390 el->el_search.patbuf[el->el_search.patlen] = 00391 '\0'; 00392 if (ret == CC_ERROR) { 00393 term_beep(el); 00394 if (el->el_history.eventno != 00395 ohisteventno) { 00396 el->el_history.eventno = 00397 ohisteventno; 00398 if (hist_get(el) == CC_ERROR) 00399 return (CC_ERROR); 00400 } 00401 el->el_line.cursor = ocursor; 00402 pchar = '?'; 00403 } else { 00404 pchar = ':'; 00405 } 00406 } 00407 ret = ce_inc_search(el, newdir); 00408 00409 if (ret == CC_ERROR && pchar == '?' && oldpchar == ':') 00410 /* 00411 * break abort of failed search at last 00412 * non-failed 00413 */ 00414 ret = CC_NORM; 00415 00416 } 00417 if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) { 00418 /* restore on normal return or error exit */ 00419 pchar = oldpchar; 00420 el->el_search.patlen = oldpatlen; 00421 if (el->el_history.eventno != ohisteventno) { 00422 el->el_history.eventno = ohisteventno; 00423 if (hist_get(el) == CC_ERROR) 00424 return (CC_ERROR); 00425 } 00426 el->el_line.cursor = ocursor; 00427 if (ret == CC_ERROR) 00428 re_refresh(el); 00429 } 00430 if (done || ret != CC_NORM) 00431 return (ret); 00432 } 00433 }
Here is the call graph for this function:

Here is the caller graph for this function:

| protected el_action_t ce_search_line | ( | EditLine * | , | |
| int | ||||
| ) |
Definition at line 514 of file search.c.
References el_line_t::buffer, CC_ERROR, CC_NORM, el_line_t::cursor, el, editline::el_line, el_match(), editline::el_search, el_line_t::limit, and el_search_t::patbuf.
00515 { 00516 char *cp = el->el_line.cursor; 00517 char *pattern = el->el_search.patbuf; 00518 char oc, *ocp; 00519 #ifdef ANCHOR 00520 ocp = &pattern[1]; 00521 oc = *ocp; 00522 *ocp = '^'; 00523 #else 00524 ocp = pattern; 00525 oc = *ocp; 00526 #endif 00527 00528 if (dir == ED_SEARCH_PREV_HISTORY) { 00529 for (; cp >= el->el_line.buffer; cp--) { 00530 if (el_match(cp, ocp)) { 00531 *ocp = oc; 00532 el->el_line.cursor = cp; 00533 return (CC_NORM); 00534 } 00535 } 00536 *ocp = oc; 00537 return (CC_ERROR); 00538 } else { 00539 for (; *cp != '\0' && cp < el->el_line.limit; cp++) { 00540 if (el_match(cp, ocp)) { 00541 *ocp = oc; 00542 el->el_line.cursor = cp; 00543 return (CC_NORM); 00544 } 00545 } 00546 *ocp = oc; 00547 return (CC_ERROR); 00548 } 00549 }
Here is the call graph for this function:

| protected el_action_t cv_csearch | ( | EditLine * | , | |
| int | , | |||
| int | , | |||
| int | , | |||
| int | ||||
| ) |
Definition at line 582 of file search.c.
References c_vcmd_t::action, lineinfo::buffer, el_chared_t::c_vcmd, CC_ERROR, CC_REFRESH, el_search_t::chacha, el_search_t::chadir, el_search_t::chatflg, el_line_t::cursor, cv_delfini(), ed_end_of_file(), el, editline::el_chared, el_getc(), el_line(), editline::el_line, editline::el_search, el_line_t::lastchar, and NOP.
Referenced by vi_next_char(), vi_prev_char(), vi_repeat_next_char(), vi_repeat_prev_char(), vi_to_next_char(), and vi_to_prev_char().
00583 { 00584 char *cp; 00585 00586 if (ch == 0) 00587 return CC_ERROR; 00588 00589 if (ch == -1) { 00590 char c; 00591 if (el_getc(el, &c) != 1) 00592 return ed_end_of_file(el, 0); 00593 ch = c; 00594 } 00595 00596 /* Save for ';' and ',' commands */ 00597 el->el_search.chacha = ch; 00598 el->el_search.chadir = direction; 00599 el->el_search.chatflg = tflag; 00600 00601 cp = el->el_line.cursor; 00602 while (count--) { 00603 if (*cp == ch) 00604 cp += direction; 00605 for (;;cp += direction) { 00606 if (cp >= el->el_line.lastchar) 00607 return CC_ERROR; 00608 if (cp < el->el_line.buffer) 00609 return CC_ERROR; 00610 if (*cp == ch) 00611 break; 00612 } 00613 } 00614 00615 if (tflag) 00616 cp -= direction; 00617 00618 el->el_line.cursor = cp; 00619 00620 if (el->el_chared.c_vcmd.action != NOP) { 00621 if (direction > 0) 00622 el->el_line.cursor++; 00623 cv_delfini(el); 00624 return CC_REFRESH; 00625 } 00626 return CC_CURSOR; 00627 }
Here is the call graph for this function:

Here is the caller graph for this function:

| protected el_action_t cv_repeat_srch | ( | EditLine * | , | |
| int | ||||
| ) |
Definition at line 556 of file search.c.
References el_line_t::buffer, CC_ERROR, ed_search_next_history(), ed_search_prev_history(), el, editline::el_errfile, editline::el_line, editline::el_search, editline::el_state, el_line_t::lastchar, el_state_t::lastcmd, el_search_t::patbuf, and el_search_t::patlen.
Referenced by vi_repeat_search_next(), and vi_repeat_search_prev().
00557 { 00558 00559 #ifdef SDEBUG 00560 (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n", 00561 c, el->el_search.patlen, el->el_search.patbuf); 00562 #endif 00563 00564 el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */ 00565 el->el_line.lastchar = el->el_line.buffer; 00566 00567 switch (c) { 00568 case ED_SEARCH_NEXT_HISTORY: 00569 return (ed_search_next_history(el, 0)); 00570 case ED_SEARCH_PREV_HISTORY: 00571 return (ed_search_prev_history(el, 0)); 00572 default: 00573 return (CC_ERROR); 00574 } 00575 }
Here is the call graph for this function:

Here is the caller graph for this function:

| protected el_action_t cv_search | ( | EditLine * | , | |
| int | ||||
| ) |
Definition at line 440 of file search.c.
References el_line_t::buffer, c_gets(), CC_ERROR, CC_REFRESH, el_line_t::cursor, ed_newline(), ed_search_next_history(), ed_search_prev_history(), el, EL_BUFSIZ, editline::el_line, editline::el_search, editline::el_state, el_line_t::lastchar, el_state_t::lastcmd, LEN, el_search_t::patbuf, el_search_t::patdir, el_search_t::patlen, and re_refresh().
Referenced by vi_search_next(), and vi_search_prev().
00441 { 00442 char ch; 00443 char tmpbuf[EL_BUFSIZ]; 00444 int tmplen; 00445 00446 #ifdef ANCHOR 00447 tmpbuf[0] = '.'; 00448 tmpbuf[1] = '*'; 00449 #endif 00450 tmplen = LEN; 00451 00452 el->el_search.patdir = dir; 00453 00454 tmplen = c_gets(el, &tmpbuf[LEN], 00455 dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" ); 00456 if (tmplen == -1) 00457 return CC_REFRESH; 00458 00459 tmplen += LEN; 00460 ch = tmpbuf[tmplen]; 00461 tmpbuf[tmplen] = '\0'; 00462 00463 if (tmplen == LEN) { 00464 /* 00465 * Use the old pattern, but wild-card it. 00466 */ 00467 if (el->el_search.patlen == 0) { 00468 re_refresh(el); 00469 return (CC_ERROR); 00470 } 00471 #ifdef ANCHOR 00472 if (el->el_search.patbuf[0] != '.' && 00473 el->el_search.patbuf[0] != '*') { 00474 (void) strncpy(tmpbuf, el->el_search.patbuf, 00475 sizeof(tmpbuf) - 1); 00476 el->el_search.patbuf[0] = '.'; 00477 el->el_search.patbuf[1] = '*'; 00478 (void) strncpy(&el->el_search.patbuf[2], tmpbuf, 00479 EL_BUFSIZ - 3); 00480 el->el_search.patlen++; 00481 el->el_search.patbuf[el->el_search.patlen++] = '.'; 00482 el->el_search.patbuf[el->el_search.patlen++] = '*'; 00483 el->el_search.patbuf[el->el_search.patlen] = '\0'; 00484 } 00485 #endif 00486 } else { 00487 #ifdef ANCHOR 00488 tmpbuf[tmplen++] = '.'; 00489 tmpbuf[tmplen++] = '*'; 00490 #endif 00491 tmpbuf[tmplen] = '\0'; 00492 (void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1); 00493 el->el_search.patlen = tmplen; 00494 } 00495 el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */ 00496 el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer; 00497 if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) : 00498 ed_search_next_history(el, 0)) == CC_ERROR) { 00499 re_refresh(el); 00500 return (CC_ERROR); 00501 } 00502 if (ch == 0033) { 00503 re_refresh(el); 00504 return ed_newline(el, 0); 00505 } 00506 return (CC_REFRESH); 00507 }
Here is the call graph for this function:

Here is the caller graph for this function:

| protected int el_match | ( | const char * | , | |
| const char * | ||||
| ) |
Definition at line 103 of file search.c.
References free, NULL, regcomp(), regexec(), and strstr().
Referenced by c_hmatch(), ce_search_line(), and el_parse().
00104 { 00105 #if defined (REGEX) 00106 regex_t re; 00107 int rv; 00108 #elif defined (REGEXP) 00109 regexp *rp; 00110 int rv; 00111 #else 00112 extern char *re_comp(const char *); 00113 extern int re_exec(const char *); 00114 #endif 00115 00116 if (strstr(str, pat) != NULL) 00117 return (1); 00118 00119 #if defined(REGEX) 00120 if (regcomp(&re, pat, 0) == 0) { 00121 rv = regexec(&re, str, 0, NULL, 0) == 0; 00122 regfree(&re); 00123 } else { 00124 rv = 0; 00125 } 00126 return (rv); 00127 #elif defined(REGEXP) 00128 if ((re = regcomp(pat)) != NULL) { 00129 rv = regexec(re, str); 00130 free((ptr_t) re); 00131 } else { 00132 rv = 0; 00133 } 00134 return (rv); 00135 #else 00136 if (re_comp(pat) != NULL) 00137 return (0); 00138 else 00139 return (re_exec(str) == 1); 00140 #endif 00141 }
Here is the call graph for this function:

Here is the caller graph for this function:

| protected void search_end | ( | EditLine * | ) |
Definition at line 79 of file search.c.
References el, el_free, editline::el_search, NULL, and el_search_t::patbuf.
Referenced by el_end(), my_instr_bin(), my_instr_simple(), r_strinstr(), String::strrstr(), String::strstr(), Item_func_replace::val_str(), and Item_func_substr_index::val_str().
00080 { 00081 00082 el_free((ptr_t) el->el_search.patbuf); 00083 el->el_search.patbuf = NULL; 00084 }
Here is the caller graph for this function:

| protected int search_init | ( | EditLine * | ) |
Definition at line 60 of file search.c.
References el_search_t::chacha, el_search_t::chadir, CHAR_FWD, el_search_t::chatflg, el, EL_BUFSIZ, el_malloc, editline::el_search, NULL, el_search_t::patbuf, el_search_t::patdir, and el_search_t::patlen.
Referenced by el_init().
00061 { 00062 00063 el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ); 00064 if (el->el_search.patbuf == NULL) 00065 return (-1); 00066 el->el_search.patlen = 0; 00067 el->el_search.patdir = -1; 00068 el->el_search.chacha = '\0'; 00069 el->el_search.chadir = CHAR_FWD; 00070 el->el_search.chatflg = 0; 00071 return (0); 00072 }
Here is the caller graph for this function:

1.4.7

