static void readline_hist_add(ReadLineState *rs, const char *cmdline) { char *hist_entry, *new_entry; int idx; if (cmdline[0] == '\0') return; new_entry = NULL; if (rs->hist_entry != -1) { /* We were editing an existing history entry: replace it */ hist_entry = rs->history[rs->hist_entry]; idx = rs->hist_entry; if (strcmp(hist_entry, cmdline) == 0) { goto same_entry; } } /* Search cmdline in history buffers */ for (idx = 0; idx < READLINE_MAX_CMDS; idx++) { hist_entry = rs->history[idx]; if (hist_entry == NULL) break; if (strcmp(hist_entry, cmdline) == 0) { same_entry: new_entry = hist_entry; /* Put this entry at the end of history */ memmove(&rs->history[idx], &rs->history[idx + 1], (READLINE_MAX_CMDS - idx + 1) * sizeof(char *)); rs->history[READLINE_MAX_CMDS - 1] = NULL; for (; idx < READLINE_MAX_CMDS; idx++) { if (rs->history[idx] == NULL) break; } break; } } if (idx == READLINE_MAX_CMDS) { /* Need to get one free slot */ free(rs->history[0]); memcpy(rs->history, &rs->history[1], (READLINE_MAX_CMDS - 1) * sizeof(char *)); rs->history[READLINE_MAX_CMDS - 1] = NULL; idx = READLINE_MAX_CMDS - 1; } if (new_entry == NULL) new_entry = strdup(cmdline); rs->history[idx] = new_entry; rs->hist_entry = -1; }