summaryrefslogtreecommitdiff
path: root/src/history.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/history.c')
-rw-r--r--src/history.c320
1 files changed, 0 insertions, 320 deletions
diff --git a/src/history.c b/src/history.c
deleted file mode 100644
index a63658c..0000000
--- a/src/history.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/* Copyright (C) 2000, 2001, 2002, 2003, 2004 Shawn Betts <sabetts@vcn.bc.ca>
- *
- * This file is part of ratpoison.
- *
- * ratpoison 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 2, or (at your option)
- * any later version.
- *
- * ratpoison 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 software; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307 USA
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <limits.h>
-
-#include "ratpoison.h"
-
-#ifdef HAVE_HISTORY
-#include "readline/history.h"
-#endif
-
-static char *
-get_history_filename (void)
-{
- char *homedir = getenv ("HOME");
- char *filename;
-
- if (homedir)
- {
- filename = xmalloc (strlen (homedir) + strlen ("/" HISTORY_FILE) + 1);
- sprintf (filename, "%s/" HISTORY_FILE, homedir);
- }
- else
- {
- filename = xstrdup (HISTORY_FILE);
- }
-
- return filename;
-}
-
-static const char *
-extract_shell_part (const char *p)
-{
- if (strncmp(p, "exec", 4) &&
- strncmp(p, "verbexec", 8))
- return NULL;
- while( *p && !isspace(*p) )
- p++;
- while( *p && isspace(*p) )
- p++;
- if (*p)
- return p;
- return NULL;
-}
-
-struct history_item {
- struct list_head node;
- char *line;
-};
-
-static struct history {
- struct list_head head, *current;
- size_t count;
-} histories[hist_COUNT];
-
-#ifndef HAVE_GETLINE
-ssize_t
-getline(char **lineptr, size_t *n, FILE *f)
-{
- size_t ofs;
-
- if (!*lineptr) {
- *lineptr = xmalloc (4096);
- *n = 4096;
- }
- ofs = 0;
- do {
- (*lineptr)[ofs] = '\0';
- if (!fgets (*lineptr, (*n) - ofs, f)) {
- /* do not tread unterminated last lines as errors,
- * (it's still a malformed text file and noone should
- * have created it) */
- return ofs?(ssize_t)ofs:-1;
- }
- ofs += strlen ((*lineptr) + ofs);
- if (ofs >= *n)
- /* should never happen... */
- return -1;
- if (ofs > 0 && (*lineptr)[ofs-1] == '\n')
- return ofs;
- if (ofs + 1 == *n) {
- if (*n >= INT_MAX - 4096)
- return -1;
- *n += 4096;
- *lineptr = xrealloc(*lineptr, *n);
- }
- } while(1);
-}
-#endif
-
-static void
-history_add_upto (int history_id, const char *item, size_t max)
-{
- struct history *h = histories + history_id;
- struct history_item *i;
-
- if (item == NULL || *item == '\0' || isspace(*item))
- return;
-
- list_last (i, &histories[history_id].head, node);
- if (i && !strcmp (i->line, item))
- return;
-
- if (history_id == hist_COMMAND) {
- const char *p = extract_shell_part (item);
- if (p)
- history_add_upto (hist_SHELLCMD, p, max);
- }
-
- if (defaults.history_compaction && max != INT_MAX) {
- struct list_head *l;
-
- for (l = h->head.prev ; l != &h->head ; l = l->prev) {
- if (!strcmp (list_entry(l, struct history_item, node)->line, item)) {
- list_del (l);
- list_add_tail (l, &h->head);
- return;
- }
- }
- }
-
- while (h->count >= max) {
- list_first (i, &h->head, node);
- if (!i) {
- h->count = 0;
- break;
- }
- list_del (&i->node);
- free (i->line);
- free (i);
- h->count--;
- }
-
- if( max == 0 )
- return;
-
- i = xmalloc (sizeof (*i));
- i->line = xstrdup (item);
-
- list_add_tail (&i->node, &h->head);
- h->count++;
-}
-
-void
-history_add (int history_id, const char *item)
-{
- history_add_upto (history_id, item, defaults.history_size);
-}
-
-void
-history_load (void)
-{
- char *filename = get_history_filename ();
- FILE *f;
- char *line = NULL;
- size_t s = 0;
- ssize_t linelen;
- int id;
-
- for (id = hist_NONE ; id < hist_COUNT ; id++ ) {
- INIT_LIST_HEAD (&histories[id].head);
- histories[id].current = &histories[id].head;
- histories[id].count = 0;
- }
-
- if (!filename)
- return;
- f = fopen (filename, "r");
- if (!f) {
- PRINT_DEBUG (("ratpoison: could not read %s - %s\n", filename, strerror (errno)));
- free (filename);
- return;
- }
-
- while ((linelen = getline (&line, &s, f)) >= 0) {
- while (linelen > 0 && (line[linelen-1] == '\n' || line[linelen-1] == '\r')) {
- line[--linelen] = '\0';
- }
- if (linelen == 0)
- continue;
- /* defaults.history_size might be only set later */
- history_add_upto (hist_COMMAND, line, INT_MAX);
- }
- if (ferror (f)) {
- PRINT_DEBUG (("ratpoison: error reading %s - %s\n", filename, strerror (errno)));
- fclose(f);
- free (filename);
- return;
- }
- if (!fclose(f))
- PRINT_DEBUG (("ratpoison: error reading %s - %s\n", filename, strerror (errno)));
- free (filename);
-}
-
-void
-history_save (void)
-{
- char *filename = get_history_filename ();
- FILE *f;
- struct history_item *item;
-
- if (!defaults.history_size)
- return;
-
- if (!filename)
- return;
- f = fopen (filename, "w");
- if (!f) {
- PRINT_DEBUG (("ratpoison: could not write %s - %s\n", filename, strerror (errno)));
- free (filename);
- return;
- }
-
- list_for_each_entry(item, &histories[hist_COMMAND].head, node) {
- fputs(item->line, f);
- putc('\n', f);
- }
-
- if (ferror (f)) {
- PRINT_DEBUG (("ratpoison: error writing %s - %s\n", filename, strerror (errno)));
- fclose(f);
- free (filename);
- return;
- }
- if (!fclose(f))
- PRINT_DEBUG (("ratpoison: error writing %s - %s\n", filename, strerror (errno)));
- free (filename);
-}
-
-void
-history_reset (void)
-{
- int id;
-
- for (id = hist_NONE ; id < hist_COUNT ; id++ )
- histories[id].current = &histories[id].head;
-}
-
-void
-history_resize (int size)
-{
- struct history_item *i;
- struct history *h;
- int id;
-
- for (id = hist_NONE ; id < hist_COUNT ; id++ ) {
- h = histories + id;
- while (h->count >= (size_t)size) {
- list_first (i, &h->head, node);
- list_del (&i->node);
- free (i->line);
- free (i);
- h->count--;
- }
- }
-}
-
-const char *
-history_previous (int history_id)
-{
- if (history_id == hist_NONE)
- return NULL;
- /* return NULL, if list empty or already at first */
- if (histories[history_id].current == histories[history_id].head.next)
- return NULL;
- histories[history_id].current = histories[history_id].current->prev;
- return list_entry(histories[history_id].current, struct history_item, node)->line;
-}
-
-const char *
-history_next (int history_id)
-{
- if (history_id == hist_NONE)
- return NULL;
- /* return NULL, if list empty or already behind last */
- if (histories[history_id].current == &histories[history_id].head)
- return NULL;
- histories[history_id].current = histories[history_id].current->next;
- if (histories[history_id].current == &histories[history_id].head)
- return NULL;
- return list_entry(histories[history_id].current, struct history_item, node)->line;
-}
-
-int history_expand_line (int history_id UNUSED, char *string, char **output)
-{
-#ifdef HAVE_HISTORY
- struct history_item *item;
-
- if (strchr (string, '!')) {
- clear_history ();
- using_history ();
- list_for_each_entry(item, &histories[history_id].head, node) {
- add_history (item->line);
- }
- return history_expand (string, output);
- }
-#endif
- *output = xstrdup(string);
- return 0;
-}