1 /* history.c -- standalone history library */ 2 3 /* Copyright (C) 1989-2017 Free Software Foundation, Inc. 4 5 This file contains the GNU History Library (History), a set of 6 routines for managing the text of previously typed lines. 7 8 History is free software: you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation, either version 3 of the License, or 11 (at your option) any later version. 12 13 History is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with History. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 /* The goal is to make the implementation transparent, so that you 23 don't have to know what data types are used, just what functions 24 you can call. I think I have done that. */ 25 #define READLINE_LIBRARY 26 27 #if defined (HAVE_CONFIG_H) 28 # include <config.h> 29 #endif 30 31 #include <stdio.h> 32 33 #if defined (HAVE_STDLIB_H) 34 # include <stdlib.h> 35 #else 36 # include "ansi_stdlib.h" 37 #endif /* HAVE_STDLIB_H */ 38 39 #if defined (HAVE_UNISTD_H) 40 # ifdef _MINIX 41 # include <sys/types.h> 42 # endif 43 # include <unistd.h> 44 #endif 45 46 #include <errno.h> 47 48 #include "history.h" 49 #include "histlib.h" 50 51 #include "xmalloc.h" 52 53 #if !defined (errno) 54 extern int errno; 55 #endif 56 57 /* How big to make the_history when we first allocate it. */ 58 #define DEFAULT_HISTORY_INITIAL_SIZE 502 59 60 #define MAX_HISTORY_INITIAL_SIZE 8192 61 62 /* The number of slots to increase the_history by. */ 63 #define DEFAULT_HISTORY_GROW_SIZE 50 64 65 static char *hist_inittime PARAMS((void)); 66 67 /* **************************************************************** */ 68 /* */ 69 /* History Functions */ 70 /* */ 71 /* **************************************************************** */ 72 73 /* An array of HIST_ENTRY. This is where we store the history. */ 74 static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL; 75 76 /* Non-zero means that we have enforced a limit on the amount of 77 history that we save. */ 78 static int history_stifled; 79 80 /* The current number of slots allocated to the input_history. */ 81 static int history_size; 82 83 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of 84 entries to remember. */ 85 int history_max_entries; 86 int max_input_history; /* backwards compatibility */ 87 88 /* The current location of the interactive history pointer. Just makes 89 life easier for outside callers. */ 90 int history_offset; 91 92 /* The number of strings currently stored in the history list. */ 93 int history_length; 94 95 /* The logical `base' of the history array. It defaults to 1. */ 96 int history_base = 1; 97 98 /* Return the current HISTORY_STATE of the history. */ 99 HISTORY_STATE * 100 history_get_history_state (void) 101 { 102 HISTORY_STATE *state; 103 104 state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE)); 105 state->entries = the_history; 106 state->offset = history_offset; 107 state->length = history_length; 108 state->size = history_size; 109 state->flags = 0; 110 if (history_stifled) 111 state->flags |= HS_STIFLED; 112 113 return (state); 114 } 115 116 /* Set the state of the current history array to STATE. */ 117 void 118 history_set_history_state (HISTORY_STATE *state) 119 { 120 the_history = state->entries; 121 history_offset = state->offset; 122 history_length = state->length; 123 history_size = state->size; 124 if (state->flags & HS_STIFLED) 125 history_stifled = 1; 126 } 127 128 /* Begin a session in which the history functions might be used. This 129 initializes interactive variables. */ 130 void 131 using_history (void) 132 { 133 history_offset = history_length; 134 } 135 136 /* Return the number of bytes that the primary history entries are using. 137 This just adds up the lengths of the_history->lines and the associated 138 timestamps. */ 139 int 140 history_total_bytes (void) 141 { 142 register int i, result; 143 144 for (i = result = 0; the_history && the_history[i]; i++) 145 result += HISTENT_BYTES (the_history[i]); 146 147 return (result); 148 } 149 150 /* Returns the magic number which says what history element we are 151 looking at now. In this implementation, it returns history_offset. */ 152 int 153 where_history (void) 154 { 155 return (history_offset); 156 } 157 158 /* Make the current history item be the one at POS, an absolute index. 159 Returns zero if POS is out of range, else non-zero. */ 160 int 161 history_set_pos (int pos) 162 { 163 if (pos > history_length || pos < 0 || !the_history) 164 return (0); 165 history_offset = pos; 166 return (1); 167 } 168 169 /* Return the current history array. The caller has to be careful, since this 170 is the actual array of data, and could be bashed or made corrupt easily. 171 The array is terminated with a NULL pointer. */ 172 HIST_ENTRY ** 173 history_list (void) 174 { 175 return (the_history); 176 } 177 178 /* Return the history entry at the current position, as determined by 179 history_offset. If there is no entry there, return a NULL pointer. */ 180 HIST_ENTRY * 181 current_history (void) 182 { 183 return ((history_offset == history_length) || the_history == 0) 184 ? (HIST_ENTRY *)NULL 185 : the_history[history_offset]; 186 } 187 188 /* Back up history_offset to the previous history entry, and return 189 a pointer to that entry. If there is no previous entry then return 190 a NULL pointer. */ 191 HIST_ENTRY * 192 previous_history (void) 193 { 194 return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL; 195 } 196 197 /* Move history_offset forward to the next history entry, and return 198 a pointer to that entry. If there is no next entry then return a 199 NULL pointer. */ 200 HIST_ENTRY * 201 next_history (void) 202 { 203 return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset]; 204 } 205 206 /* Return the history entry which is logically at OFFSET in the history array. 207 OFFSET is relative to history_base. */ 208 HIST_ENTRY * 209 history_get (int offset) 210 { 211 int local_index; 212 213 local_index = offset - history_base; 214 return (local_index >= history_length || local_index < 0 || the_history == 0) 215 ? (HIST_ENTRY *)NULL 216 : the_history[local_index]; 217 } 218 219 HIST_ENTRY * 220 alloc_history_entry (char *string, char *ts) 221 { 222 HIST_ENTRY *temp; 223 224 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); 225 226 temp->line = string ? savestring (string) : string; 227 temp->data = (char *)NULL; 228 temp->timestamp = ts; 229 230 return temp; 231 } 232 233 time_t 234 history_get_time (HIST_ENTRY *hist) 235 { 236 char *ts; 237 time_t t; 238 239 if (hist == 0 || hist->timestamp == 0) 240 return 0; 241 ts = hist->timestamp; 242 if (ts[0] != history_comment_char) 243 return 0; 244 errno = 0; 245 t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */ 246 if (errno == ERANGE) 247 return (time_t)0; 248 return t; 249 } 250 251 static char * 252 hist_inittime (void) 253 { 254 time_t t; 255 char ts[64], *ret; 256 257 t = (time_t) time ((time_t *)0); 258 #if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */ 259 snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t); 260 #else 261 sprintf (ts, "X%lu", (unsigned long) t); 262 #endif 263 ret = savestring (ts); 264 ret[0] = history_comment_char; 265 266 return ret; 267 } 268 269 /* Place STRING at the end of the history list. The data field 270 is set to NULL. */ 271 void 272 add_history (const char *string) 273 { 274 HIST_ENTRY *temp; 275 int new_length; 276 277 if (history_stifled && (history_length == history_max_entries)) 278 { 279 register int i; 280 281 /* If the history is stifled, and history_length is zero, 282 and it equals history_max_entries, we don't save items. */ 283 if (history_length == 0) 284 return; 285 286 /* If there is something in the slot, then remove it. */ 287 if (the_history[0]) 288 (void) free_history_entry (the_history[0]); 289 290 /* Copy the rest of the entries, moving down one slot. Copy includes 291 trailing NULL. */ 292 memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *)); 293 294 new_length = history_length; 295 history_base++; 296 } 297 else 298 { 299 if (history_size == 0) 300 { 301 if (history_stifled && history_max_entries > 0) 302 history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE) 303 ? MAX_HISTORY_INITIAL_SIZE 304 : history_max_entries + 2; 305 else 306 history_size = DEFAULT_HISTORY_INITIAL_SIZE; 307 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *)); 308 new_length = 1; 309 } 310 else 311 { 312 if (history_length == (history_size - 1)) 313 { 314 history_size += DEFAULT_HISTORY_GROW_SIZE; 315 the_history = (HIST_ENTRY **) 316 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *)); 317 } 318 new_length = history_length + 1; 319 } 320 } 321 322 temp = alloc_history_entry ((char *)string, hist_inittime ()); 323 324 the_history[new_length] = (HIST_ENTRY *)NULL; 325 the_history[new_length - 1] = temp; 326 history_length = new_length; 327 } 328 329 /* Change the time stamp of the most recent history entry to STRING. */ 330 void 331 add_history_time (const char *string) 332 { 333 HIST_ENTRY *hs; 334 335 if (string == 0 || history_length < 1) 336 return; 337 hs = the_history[history_length - 1]; 338 FREE (hs->timestamp); 339 hs->timestamp = savestring (string); 340 } 341 342 /* Free HIST and return the data so the calling application can free it 343 if necessary and desired. */ 344 histdata_t 345 free_history_entry (HIST_ENTRY *hist) 346 { 347 histdata_t x; 348 349 if (hist == 0) 350 return ((histdata_t) 0); 351 FREE (hist->line); 352 FREE (hist->timestamp); 353 x = hist->data; 354 xfree (hist); 355 return (x); 356 } 357 358 HIST_ENTRY * 359 copy_history_entry (HIST_ENTRY *hist) 360 { 361 HIST_ENTRY *ret; 362 char *ts; 363 364 if (hist == 0) 365 return hist; 366 367 ret = alloc_history_entry (hist->line, (char *)NULL); 368 369 ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp; 370 ret->timestamp = ts; 371 372 ret->data = hist->data; 373 374 return ret; 375 } 376 377 /* Make the history entry at WHICH have LINE and DATA. This returns 378 the old entry so you can dispose of the data. In the case of an 379 invalid WHICH, a NULL pointer is returned. */ 380 HIST_ENTRY * 381 replace_history_entry (int which, const char *line, histdata_t data) 382 { 383 HIST_ENTRY *temp, *old_value; 384 385 if (which < 0 || which >= history_length) 386 return ((HIST_ENTRY *)NULL); 387 388 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); 389 old_value = the_history[which]; 390 391 temp->line = savestring (line); 392 temp->data = data; 393 temp->timestamp = savestring (old_value->timestamp); 394 the_history[which] = temp; 395 396 return (old_value); 397 } 398 399 /* Append LINE to the history line at offset WHICH, adding a newline to the 400 end of the current line first. This can be used to construct multi-line 401 history entries while reading lines from the history file. */ 402 void 403 _hs_append_history_line (int which, const char *line) 404 { 405 HIST_ENTRY *hent; 406 size_t newlen, curlen, minlen; 407 char *newline; 408 409 hent = the_history[which]; 410 curlen = strlen (hent->line); 411 minlen = curlen + strlen (line) + 2; /* min space needed */ 412 if (curlen > 256) /* XXX - for now */ 413 { 414 newlen = 512; /* now realloc in powers of 2 */ 415 /* we recalcluate every time; the operations are cheap */ 416 while (newlen < minlen) 417 newlen <<= 1; 418 } 419 else 420 newlen = minlen; 421 /* Assume that realloc returns the same pointer and doesn't try a new 422 alloc/copy if the new size is the same as the one last passed. */ 423 newline = realloc (hent->line, newlen); 424 if (newline) 425 { 426 hent->line = newline; 427 hent->line[curlen++] = '\n'; 428 strcpy (hent->line + curlen, line); 429 } 430 } 431 432 /* Replace the DATA in the specified history entries, replacing OLD with 433 NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace 434 all of the history entries where entry->data == OLD; WHICH == -2 means 435 to replace the `newest' history entry where entry->data == OLD; and 436 WHICH >= 0 means to replace that particular history entry's data, as 437 long as it matches OLD. */ 438 void 439 _hs_replace_history_data (int which, histdata_t *old, histdata_t *new) 440 { 441 HIST_ENTRY *entry; 442 register int i, last; 443 444 if (which < -2 || which >= history_length || history_length == 0 || the_history == 0) 445 return; 446 447 if (which >= 0) 448 { 449 entry = the_history[which]; 450 if (entry && entry->data == old) 451 entry->data = new; 452 return; 453 } 454 455 last = -1; 456 for (i = 0; i < history_length; i++) 457 { 458 entry = the_history[i]; 459 if (entry == 0) 460 continue; 461 if (entry->data == old) 462 { 463 last = i; 464 if (which == -1) 465 entry->data = new; 466 } 467 } 468 if (which == -2 && last >= 0) 469 { 470 entry = the_history[last]; 471 entry->data = new; /* XXX - we don't check entry->old */ 472 } 473 } 474 475 /* Remove history element WHICH from the history. The removed 476 element is returned to you so you can free the line, data, 477 and containing structure. */ 478 HIST_ENTRY * 479 remove_history (int which) 480 { 481 HIST_ENTRY *return_value; 482 register int i; 483 #if 1 484 int nentries; 485 HIST_ENTRY **start, **end; 486 #endif 487 488 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0) 489 return ((HIST_ENTRY *)NULL); 490 491 return_value = the_history[which]; 492 493 #if 1 494 /* Copy the rest of the entries, moving down one slot. Copy includes 495 trailing NULL. */ 496 nentries = history_length - which; 497 start = the_history + which; 498 end = start + 1; 499 memmove (start, end, nentries * sizeof (HIST_ENTRY *)); 500 #else 501 for (i = which; i < history_length; i++) 502 the_history[i] = the_history[i + 1]; 503 #endif 504 505 history_length--; 506 507 return (return_value); 508 } 509 510 HIST_ENTRY ** 511 remove_history_range (int first, int last) 512 { 513 HIST_ENTRY **return_value; 514 register int i; 515 int nentries; 516 HIST_ENTRY **start, **end; 517 518 if (the_history == 0 || history_length == 0) 519 return ((HIST_ENTRY **)NULL); 520 if (first < 0 || first >= history_length || last < 0 || last >= history_length) 521 return ((HIST_ENTRY **)NULL); 522 if (first > last) 523 return (HIST_ENTRY **)NULL; 524 525 nentries = last - first + 1; 526 return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *)); 527 if (return_value == 0) 528 return return_value; 529 530 /* Return all the deleted entries in a list */ 531 for (i = first ; i <= last; i++) 532 return_value[i - first] = the_history[i]; 533 return_value[i - first] = (HIST_ENTRY *)NULL; 534 535 /* Copy the rest of the entries, moving down NENTRIES slots. Copy includes 536 trailing NULL. */ 537 start = the_history + first; 538 end = the_history + last + 1; 539 memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *)); 540 541 history_length -= nentries; 542 543 return (return_value); 544 } 545 546 /* Stifle the history list, remembering only MAX number of lines. */ 547 void 548 stifle_history (int max) 549 { 550 register int i, j; 551 552 if (max < 0) 553 max = 0; 554 555 if (history_length > max) 556 { 557 /* This loses because we cannot free the data. */ 558 for (i = 0, j = history_length - max; i < j; i++) 559 free_history_entry (the_history[i]); 560 561 history_base = i; 562 for (j = 0, i = history_length - max; j < max; i++, j++) 563 the_history[j] = the_history[i]; 564 the_history[j] = (HIST_ENTRY *)NULL; 565 history_length = j; 566 } 567 568 history_stifled = 1; 569 max_input_history = history_max_entries = max; 570 } 571 572 /* Stop stifling the history. This returns the previous maximum 573 number of history entries. The value is positive if the history 574 was stifled, negative if it wasn't. */ 575 int 576 unstifle_history (void) 577 { 578 if (history_stifled) 579 { 580 history_stifled = 0; 581 return (history_max_entries); 582 } 583 else 584 return (-history_max_entries); 585 } 586 587 int 588 history_is_stifled (void) 589 { 590 return (history_stifled); 591 } 592 593 void 594 clear_history (void) 595 { 596 register int i; 597 598 /* This loses because we cannot free the data. */ 599 for (i = 0; i < history_length; i++) 600 { 601 free_history_entry (the_history[i]); 602 the_history[i] = (HIST_ENTRY *)NULL; 603 } 604 605 history_offset = history_length = 0; 606 history_base = 1; /* reset history base to default */ 607 } 608