Files
Fish (David B. Trout) d573026b5b Fix some GCC warnings
2018-04-15 01:54:47 -07:00

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;
}