/*
Silky - A GTK+ client for SILC.
Copyright (C) 2003, 2004, 2005 Toni Willberg
- Command history management functions
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
http://silky.sourceforge.net/
*/
#include <glib.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "cmdhistory.h"
#include "log.h"
/* this points to first (newest) cmd_history entry.
->next == NULL, ->prev == previous (older) entry */
SilkyCmdHistoryItem *cmd_history = NULL;
/* this points to currently displayed cmd_history entry, when browsing.
SHOULD BE NULL WHEN NOT BROWSING! */
SilkyCmdHistoryItem *current_cmd_history_entry = NULL;
char *cmd_history_prev(void) {
if( !cmd_history ) {
debug("no command history yet");
return(NULL);
}
if( !current_cmd_history_entry ) {
debug("setting current_cmd_history_entry to newest history entry");
current_cmd_history_entry = cmd_history;
return(current_cmd_history_entry->text);
}
if( !current_cmd_history_entry->prev ) {
debug("already at oldest command history entry, ignoring...");
return("");
}
current_cmd_history_entry = current_cmd_history_entry->prev;
return(current_cmd_history_entry->text);
}
char *cmd_history_next(void) {
if( !cmd_history ) {
debug("no command history yet");
return("");
}
if( !current_cmd_history_entry ) {
debug("not browsing command history, ignoring");
return("");
}
if( !current_cmd_history_entry->next ) {
debug("already at newest command history entry, setting current_cmd_history_entry to NULL");
current_cmd_history_entry = NULL;
return("");
}
current_cmd_history_entry = current_cmd_history_entry->next;
return(current_cmd_history_entry->text);
}
void cmd_history_push(char *text) {
SilkyCmdHistoryItem *c = NULL, *oldc = NULL;
int count;
int length=0;
if( !g_utf8_validate(text, g_utf8_strlen(text, -1), NULL) ) {
debug("non-utf8 string passed as argument");
return;
}
/* first, let's test if entered command is the same as last entry in history.
no point in having it added twice */
if( cmd_history && !strcmp(text, cmd_history->text) ) {
debug("Entered command equals last command in history, will not duplicate it");
return;
}
/* now let's add newest entry to the beginning, so cmd_history points to it */
debug("adding new command cmd_history entry: '%s'", text);
if( !(c = malloc( sizeof( SilkyCmdHistoryItem ) )) ) {
debug_error("can not allocate memory for new command history entry!!!");
}
c->next = NULL;
/* cut */
length = g_utf8_strlen(text,-1);
if( length > 256 ) length = 256;
g_utf8_strncpy(c->text, text, length); /* populate it */
if(cmd_history) { /* if some command cmd_history already exists... */
c->prev = cmd_history; /* link it to current newest entry */
cmd_history->next = c; /* link current newest entry to it */
} else c->prev = NULL;
cmd_history = c; /* and finally make it the newest entry */
/* if addition was succesful, let's expire oldest entry */
debug("expiring oldest command cmd_history entry");
for( count = 0,oldc = cmd_history;oldc && oldc->prev && count < CMD_HISTORY_DEPTH;oldc=oldc->prev,count++ ) {} /* iterate to oldest entry */
if( count < CMD_HISTORY_DEPTH ) return;
if( c != oldc ) { /* only expire if it's not currently added entry (happens when there's only one) */
oldc->next->prev = NULL; /* unlink it */
free(oldc); /* and release it from memory */
}
}
syntax highlighted by Code2HTML, v. 0.9.1