static void isearch_again(ISearchState new_isearch_state, XEvent *event) { if (!gdb->isReadyWithPrompt()) return; if (isearch_state == ISEARCH_NONE) isearch_string = ""; if (isearch_state == new_isearch_state) { // Same state - search again int history = search_history(isearch_string, int(isearch_state), true); if (history < 0) XtCallActionProc(gdb_w, "beep", event, 0, 0); else isearch_done(XtPointer(history), 0); } else { isearch_state = new_isearch_state; show_isearch(); } }
// Handle incremental searches; return true if processed static bool do_isearch(Widget, XmTextVerifyCallbackStruct *change) { if (isearch_state == ISEARCH_NONE) return false; string saved_isearch_string = isearch_string; bool processed = false; if (change->startPos == change->endPos) { // Character insertion string input = string(change->text->ptr, change->text->length); if (!input.contains('\n', -1)) { // Add to current search string isearch_string += input; processed = true; } } else if (change->endPos - change->startPos == 1) { // Backspace - remove last character from search string if (!isearch_string.empty()) isearch_string.after(int(isearch_string.length()) - 2) = ""; else clear_isearch(true, false); processed = true; } if (processed) { int history = -1; if (isearch_string.empty() || current_line().contains(isearch_string)) { // Search string found in current line history = -1; } else { history = search_history(isearch_string, int(isearch_state)); if (history < 0) { // Search string not found in history if (change->event != 0) XtCallActionProc(gdb_w, "beep", change->event, 0, 0); isearch_string = saved_isearch_string; } } // Make this a no-op if (!have_isearch_line) { isearch_line = current_line(); have_isearch_line = true; } // Redraw current line with appropriate prompt. XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 0, isearch_done, XtPointer(history)); // Upon the next call to gdbMotionCB(), clear ISearch mode, // unless it immediately follows this one. isearch_motion_ok = true; XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 10, set_isearch_motion_ok, XtPointer(false)); } return processed; }
/* PROCESS_HISTORY_DIRECTIVE -- Transform a history directive into an * executable command or command block. There are two classes of * directives: (1) string substitution editing of the last command block, * and (2) search for an earlier command by some means and return that. * If ":p" follows a directive, we generate the command and return false * (no execute) as the function value. Any text which follows the directive * is appended to the new command block. */ int process_history_directive ( char *directive, char *new_command_block ) { register char *ip, *op, *p; char last_command_block[SZ_CMDBLK+1]; int execute=1, edit=0; int record; char *rindex(); ip = directive + 1; /* skip the '^' */ op = new_command_block; /* Chop the newline. */ if ((p = rindex (ip, '\n')) != NULL) *p = EOS; /* Scan the directive string to determine whether or not we have * an edit directive. We have an edit directive if there is a second * (unescaped) history metacharacter in the directive. */ for (p=ip, edit=0; *p != EOS; p++) if (*p == '\\' && *(p+1) != EOS) p++; else if (*p == HISTCHAR) { edit = 1; break; } /* Directives "^^", "^str1^str2^", and "^str1^str2^g". */ if (edit) { /* Get last command and edit it */ if (get_history (1, last_command_block, SZ_CMDBLK) == ERR) cl_error (E_UERR, "Nothing in history buffer to edit"); ip = directive + stredit (directive, last_command_block, new_command_block); /* Directives "^absnum" and "-relnum". */ } else if ((*ip == '-' && isdigit (*(ip+1))) || isdigit (*ip)) { if (*ip == '-') record = -atoi(ip++); else record = histnum - atoi(ip) + 1; if (get_history (record, new_command_block, SZ_CMDBLK) == ERR) cl_error (E_UERR, "History record not found"); while (isdigit (*ip)) ip++; /* Directives "^", "^str", and "^?str". */ } else ip = directive + search_history (directive, new_command_block); /* Check for the ":p" no execute suffix */ execute = (strncmp (ip, NO_EXECUTE, strlen(NO_EXECUTE)) != 0); if (!execute) ip += strlen (NO_EXECUTE); /* Append any text remaining in the history directive to the new * command block, BEFORE the final newline. */ op += strlen (new_command_block); while (isspace (*(op-1))) --op; expand_history_macros (ip, op); /* Make sure the new command line ends with a newline. */ while (*op != EOS) op++; while (isspace (*(op-1))) --op; *op++ = '\n'; *op = EOS; return (execute); }