/* Copyright (C) 2008 Emmanuel Varoquaux This file is part of XOS. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "xmalloc.h" #include #define HISTSIZE 500 #define HISTORY_GROW_SIZE 50 static int history_max_entries = HISTSIZE; static HIST_ENTRY **history = NULL; static int history_size = 0; static int history_length = 0; static int history_offset; static void init_hist_entry(HIST_ENTRY *hist_entry, const char *string) { hist_entry->line = xstrdup(string); hist_entry->data = NULL; } static void destroy_hist_entry(HIST_ENTRY *hist_entry) { free(hist_entry->line); } static HIST_ENTRY *alloc_hist_entry(const char *string) { HIST_ENTRY *hist_entry; hist_entry = xmalloc(sizeof (HIST_ENTRY)); init_hist_entry(hist_entry, string); return hist_entry; } static void free_hist_entry(HIST_ENTRY *hist_entry) { destroy_hist_entry(hist_entry); free(hist_entry); } void __attribute__ ((weak, visibility ("default"))) using_history() { history_offset = history_length; } void __attribute__ ((weak, visibility ("default"))) add_history(const char *string) { int i; if (history_length == history_max_entries) { if (history_length == 0) return; free_hist_entry(history[0]); for (i = 0; i < history_length - 1; i++) history[i] = history[i + 1]; } else { if (!history) { history = xmalloc(HISTORY_GROW_SIZE * sizeof (HIST_ENTRY *)); history_size = HISTORY_GROW_SIZE; } else if (history_length == history_size - 1) { history = xrealloc(history, (history_size + HISTORY_GROW_SIZE) * sizeof (HIST_ENTRY *)); history_size += HISTORY_GROW_SIZE; } history_length++; } history[history_length - 1] = alloc_hist_entry(string); history[history_length] = NULL; } HIST_ENTRY __attribute__ ((weak, visibility ("default"))) **history_list() { return history; } int __attribute__ ((weak, visibility ("default"))) where_history() { return history_offset; } HIST_ENTRY __attribute__ ((weak, visibility ("default"))) *current_history() { return history ? history[history_offset] : NULL; } int __attribute__ ((weak, visibility ("default"))) history_set_pos(int pos) { if (pos < 0 || pos > history_length) return 0; history_offset = pos; return 1; } HIST_ENTRY __attribute__ ((weak, visibility ("default"))) *previous_history() { if (history_offset == 0) return NULL; history_offset--; return history[history_offset]; } HIST_ENTRY __attribute__ ((weak, visibility ("default"))) *next_history() { if (history_offset == history_length) return NULL; history_offset++; return history[history_offset]; }