mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-07-26 02:29:51 +02:00
309 lines
9.0 KiB
C
309 lines
9.0 KiB
C
/* HISTORY.C (C) Copyright Roger Bowler, 1999-2012 */
|
|
/* Hercules Command History Processes */
|
|
/* */
|
|
/* Released under "The Q Public License Version 1" */
|
|
/* (http://www.hercules-390.org/herclic.html) as modifications to */
|
|
/* Hercules. */
|
|
|
|
#include "hstdinc.h"
|
|
|
|
#include "hercules.h"
|
|
#include "history.h"
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* HISTORY structure */
|
|
/*-------------------------------------------------------------------*/
|
|
typedef struct HISTORY HISTORY;
|
|
struct HISTORY
|
|
{
|
|
int number;
|
|
char* cmdline;
|
|
HISTORY* prev;
|
|
HISTORY* next;
|
|
};
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Global variables */
|
|
/*-------------------------------------------------------------------*/
|
|
HISTORY* history_lines = NULL; /* list begin (oldest cmd) */
|
|
HISTORY* history_lines_end = NULL; /* list end (most recent cmd) */
|
|
HISTORY* history_ptr = NULL; /* last key press retrieved cmd */
|
|
HISTORY* backup = NULL; /* saved last removed cmd */
|
|
int history_count = 0; /* for line numbering */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Public variables */
|
|
/*-------------------------------------------------------------------*/
|
|
/* used in panel.c to see if there was history command requested */
|
|
/* and returns that command */
|
|
/*-------------------------------------------------------------------*/
|
|
char* historyCmdLine = NULL;
|
|
int history_requested = 0;
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* copy_to_historyCmdLine */
|
|
/*-------------------------------------------------------------------*/
|
|
void copy_to_historyCmdLine( char* cmdline )
|
|
{
|
|
size_t size = strlen( cmdline ) + 1;
|
|
free( historyCmdLine );
|
|
historyCmdLine = malloc( size );
|
|
strlcpy( historyCmdLine, cmdline, size );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* history_init - initialize environment */
|
|
/*-------------------------------------------------------------------*/
|
|
int history_init()
|
|
{
|
|
history_lines = NULL;
|
|
history_lines_end = NULL;
|
|
history_ptr = NULL;
|
|
backup = NULL;
|
|
history_count = 0;
|
|
|
|
historyCmdLine = (char*) malloc( CMD_SIZE + 1 );
|
|
history_requested = 0;
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* history_add - add commandline to history list */
|
|
/*-------------------------------------------------------------------*/
|
|
int history_add( char* cmdline )
|
|
{
|
|
HISTORY* tmp;
|
|
size_t size;
|
|
|
|
/* if there is some backup line remaining, remove it */
|
|
if (backup)
|
|
{
|
|
free( backup->cmdline );
|
|
free( backup );
|
|
backup = NULL;
|
|
}
|
|
|
|
/* If last line is exactly the same as this line
|
|
ignore and return to caller
|
|
*/
|
|
if (history_lines && !strcmp( cmdline, history_lines_end->cmdline ))
|
|
{
|
|
history_ptr = NULL;
|
|
return 0;
|
|
}
|
|
|
|
/* Allocate space and copy string */
|
|
tmp = (HISTORY*) malloc( sizeof( HISTORY ));
|
|
size = strlen( cmdline ) + 1;
|
|
tmp->cmdline = (char*) malloc(size);
|
|
strlcpy( tmp->cmdline, cmdline, size );
|
|
tmp->next = NULL;
|
|
tmp->prev = NULL;
|
|
tmp->number = ++history_count;
|
|
|
|
if (!history_lines)
|
|
{
|
|
/* first in list */
|
|
history_lines = tmp;
|
|
history_lines_end = tmp;
|
|
}
|
|
else
|
|
{
|
|
tmp->prev = history_lines_end;
|
|
history_lines_end->next = tmp;
|
|
history_lines_end = tmp;
|
|
}
|
|
|
|
history_ptr = NULL;
|
|
|
|
if (history_count > HISTORY_MAX)
|
|
{
|
|
/* If we are over maximum number of lines in history list,
|
|
oldest one should be deleted, but we don't know whether
|
|
history_remove will be called or not, so the oldest line
|
|
is just saved instead, to be deleted on the next call.
|
|
*/
|
|
backup = history_lines;
|
|
history_lines = history_lines->next;
|
|
backup->next = NULL;
|
|
history_lines->prev = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* history_remove */
|
|
/*-------------------------------------------------------------------*/
|
|
/* Remove last line from history list. */
|
|
/* Called only when history command is invoked. */
|
|
/*-------------------------------------------------------------------*/
|
|
int history_remove()
|
|
{
|
|
HISTORY* tmp;
|
|
|
|
if (!history_lines)
|
|
return 0;
|
|
|
|
if (history_lines == history_lines_end)
|
|
{
|
|
ASSERT( !history_lines->next );
|
|
ASSERT( history_count == 1 );
|
|
|
|
free( history_lines->cmdline );
|
|
free( history_lines );
|
|
|
|
history_lines = NULL;
|
|
history_lines_end = NULL;
|
|
|
|
history_count--;
|
|
|
|
return 0;
|
|
}
|
|
|
|
tmp = history_lines_end->prev;
|
|
tmp->next = NULL;
|
|
|
|
free( history_lines_end->cmdline );
|
|
free( history_lines_end );
|
|
|
|
history_count--;
|
|
history_lines_end = tmp;
|
|
|
|
if (backup)
|
|
{
|
|
backup->next = history_lines;
|
|
history_lines->prev = backup;
|
|
history_lines = backup;
|
|
backup = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* history_next */
|
|
/*-------------------------------------------------------------------*/
|
|
int history_next()
|
|
{
|
|
if (!history_ptr)
|
|
{
|
|
if (!(history_ptr = history_lines_end))
|
|
return -1;
|
|
copy_to_historyCmdLine( history_ptr->cmdline );
|
|
return 0;
|
|
}
|
|
|
|
if (!history_ptr->next) history_ptr = history_lines;
|
|
else history_ptr = history_ptr->next;
|
|
|
|
copy_to_historyCmdLine( history_ptr->cmdline );
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* history_prev */
|
|
/*-------------------------------------------------------------------*/
|
|
int history_prev()
|
|
{
|
|
if (!history_ptr)
|
|
{
|
|
if (!(history_ptr = history_lines_end))
|
|
return -1;
|
|
copy_to_historyCmdLine( history_ptr->cmdline );
|
|
return 0;
|
|
}
|
|
|
|
if (!history_ptr->prev) history_ptr = history_lines_end;
|
|
else history_ptr = history_ptr->prev;
|
|
|
|
copy_to_historyCmdLine( history_ptr->cmdline );
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* history_relative_line */
|
|
/*-------------------------------------------------------------------*/
|
|
int history_relative_line( int rline )
|
|
{
|
|
HISTORY* tmp = history_lines_end;
|
|
char buf[80];
|
|
|
|
if (-rline > HISTORY_MAX)
|
|
{
|
|
MSGBUF( buf, "History limited to last %d commands", HISTORY_MAX );
|
|
// "%s"
|
|
WRMSG( HHC02293, "E", buf );
|
|
return -1;
|
|
}
|
|
|
|
if (-rline > history_count)
|
|
{
|
|
MSGBUF( buf, "Only %d commands in history", history_count );
|
|
// "%s"
|
|
WRMSG( HHC02293, "E", buf );
|
|
return -1;
|
|
}
|
|
|
|
while (rline < -1)
|
|
{
|
|
tmp = tmp->prev;
|
|
rline++;
|
|
}
|
|
|
|
copy_to_historyCmdLine( tmp->cmdline );
|
|
|
|
history_ptr = NULL;
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* history_absolute_line */
|
|
/*-------------------------------------------------------------------*/
|
|
int history_absolute_line( int aline )
|
|
{
|
|
HISTORY* tmp = history_lines_end;
|
|
int lowlimit;
|
|
char buf[80];
|
|
|
|
if (!history_count)
|
|
{
|
|
// "%s"
|
|
WRMSG( HHC02293, "E", "History empty" );
|
|
return -1;
|
|
}
|
|
|
|
lowlimit = (history_count - HISTORY_MAX);
|
|
|
|
if (aline > history_count || aline <= lowlimit)
|
|
{
|
|
MSGBUF( buf, "Only commands %d-%d are in history",
|
|
lowlimit < 0 ? 1 : lowlimit + 1, history_count );
|
|
// "%s"
|
|
WRMSG( HHC02293, "E", buf );
|
|
return -1;
|
|
}
|
|
|
|
while (tmp->number != aline)
|
|
tmp = tmp->prev;
|
|
|
|
copy_to_historyCmdLine( tmp->cmdline );
|
|
|
|
history_ptr = NULL;
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* history_show - show list of lines in history */
|
|
/*-------------------------------------------------------------------*/
|
|
int history_show()
|
|
{
|
|
HISTORY* tmp = history_lines;
|
|
|
|
while (tmp)
|
|
{
|
|
// "Index %3d: %s"
|
|
WRMSG( HHC02273, "I", tmp->number, tmp->cmdline );
|
|
tmp = tmp->next;
|
|
}
|
|
return 0;
|
|
}
|